所有権

リストを作ることができるようになったので,次はリストで何かできるようになると いいですね.それを実現するために普通の(スタティックでない)メソッドを使います. メソッドはselfという型のない引数を持つ,関数の特別な形です:

fn foo(self, arg2: Type2) -> ReturnType {
    // body
}

selfは主に3つの形をとります:self&mut self,そして &selfです. これらはRustにおける所有権の3つの形に対応しています:

  • self - 値
  • &mut self - 可変参照
  • &self - 共有参照

値は本物の所有権を表します.この値を煮るなり焼くなり動かすなり破壊するなり変更するなり 参照を貸し出すなり自由です.何かの値を渡したとき,それは渡されたところにムーブされます. そして渡されたほうがその値の所有権を持つようになり,渡したほうからはアクセスできなく なります.なので,たいていのメソッドではselfを使いません.pushやpopするたびに アクセスできなくなるリストを使うのはそうとうアホですしね!

可変参照は,所有権を持たない値の一時的かつ排他的なアクセスを表します. 可変参照を持つ値に対して何をしても大丈夫ですが,所有権を返すときに有効な状態に しておく必要があります(でないと借りた人に失礼ですからね!).値を完全に書き換えて しまうこともできるので,別の値とすり替えるようなこともできます.値のすり替えは このあと沢山やることになります.&mutに対して唯一できないことは代わりの値を 用意せずにムーブしてしまうことです.&mut selfをもつメソッドはselfに対して 変更を加えたいときにとても有用なメソッドです.

共有参照は,所有権を持たない値の一時的で,共有されたアクセスを表します. 共有されているので,値に対して変更を加えることはできません.&は値を 博物館のガラスケースに入れてるようなものだと考えてください.selfの状態を 取得したいだけのときは&が特に有用です.

あとでこのルールは回避可能であることを見ていきます.共有参照が不変参照と 呼ばれていないのはそういう理由からです.可変参照は唯一無二参照とか 呼ばれるべきかもしれませんが,所有権と値の可変性は99%の場合直感に即している ことがわかりました.