ご存知の通り Rust 言語はとても厳格な型システムを持っています。
そのためノリで書こうとしてもコンパイラや Language Server から「ここ、型が合わないよ」と言われて実行すらさせてもらえないことが稀によくあります。
ですが、そんなことばかり言っても初学者にとってはテン下げだと思うのでバイブス重視での解説を試みます。
今回のテーマは「借用」です。
変数 x
や型 T
の前に &
がついたら借用
変数 x
が &x
になってたり、型 T
が &T
になってたりしたら借用です。
&mut x
とか &mut T
みたいなパターンもあって、なんか &
がついてるのでこれも借用です。
「借用」とは何か?これからノリで説明します。
関数の型を見ていく
fn f(arg: T)
- 引数を食うやつ
引数の型が T
になってたら、その関数は引数を食うやつです。
与えた引数は食われるので返ってきません。
「まぁ目的さえ達成できれば食われてもいいよ、どうぞ」みたいなときはこれ。
fn f(arg: &T)
- 引数を見るだけのやつ
引数の型に &
がついてたら、引数を見るだけのやつです。
なんか条件演算につかったり、表示してみたり、とにかく見るだけ。食わないし、いじったりしない。
いちばん無難なやつ。とりあえず &T
でいけそうなら &T
で行っときたい。
fn f(arg: &mut T)
- 引数をしれっと変えるやつ
&mut
は引数を食わないけど、しれっと変えたりするやつです。
"mut" は "mutate" とか "mutable" の略、たぶん。
配列のソートとかみたいに「いい感じに変えるけど、最終的にはお返しします」みたいな関数はまぁまぁあります。
「元の値はもう使わんし、いい感じに変えちゃってどーぞ」みたいなときはこれ。
fn f(arg: mut T)
- んなもんは無い
mut T
のパターンは無い。
&
がついていないパターンなので引数は食われます。食った後に変更されるかどうかなんて誰も興味ありません。
「あーあ、食われちゃった」で話は終わりです。
なので mut T
なんてパターンはなくて、そういうときは T
と書けばいいです。
メソッドの型も見ていく
Rust にも一応メソッド呼び出しみたいなものはあります。
fn f(self, arg: T)
みたいな感じで第一引数に self
が書いてあります。 Python みたいだね。
それを踏まえて。
fn f(self)
- インスタンスをぶち壊すやつ
T
のときに引数が食われていたのと同様に self
と書くと self
を食うメソッドになります。
このタイプのメソッドを一回呼んだが最後、インスタンスは食われてぶち壊されると思ってください。
「それでは困る」という場合はメソッドの最後で return self;
的なことをしてあげるとまだ実用的かも。
fn f(&self)
- 普通のやつ
メソッド定義の型で一番普通なやつ。
self
を見るだけ。奪わない・食わない・壊さない。とても普通。
fn f(&mut self)
- 内部状態を変化させるやつ
一般的な言語で言う「内部状態を変化させる」メソッド。準普通。
「あー、 &mut self
だから内部状態が変化するんだなぁー」と思って見ていればいいです。
fn f(mut self)
- そんなものは無い
このパターンは無い。
無いということだけ知っておけばよい。
まとめ
T
- 食うやつ&T
- 見るだけのやつ&mut T
- しれっと変えるやつ
そんな感じ。
ドントウォーリー・ビーハッピー
私からは以上です。
ロジック重視の解説
本を読みましょう。