Rustの所有権について
今回はRustの借用/参照と所有権について雑に書きなぐる.
所有権とは
所有権はRustに導入されているゼロコスト抽象化*1の例の一つ. 具体的な例を上げると, 変数が非primitiveな型*2である場合に, 以下のような問題に直面する.
fn some(x: Vec<i8>) { // TODO: } fn main() { let x = vec![2]; some(x); println!("{:?}", x); }
この処理を実行してみる. 内容は順にxにVectorを代入して, xの中身をprintlnで表示している. someの中身は重要ではないので無視する. 実行してみると次のようなエラーが発生する.
borrow of moved value: `x`
意訳するとxが移動された後に借用された という意味になる. 実はこの移動されたというのは, 所有権が移動したという意味だ. xの所有権はmain関数のスコープにあった訳だが, some(x) を呼び出した時点で所有権がsomeに移動する. つまり, それ以降からxを参照しようとすると, 所有権がないのでエラーになる.
参照と借用
これを回避するためにはxの所有権を渡すのではなく, xを借用させれば良い.
fn some(x: &Vec<i8>) { // TODO: } fn main() { let x = vec![2]; some(&x); println!("{:?}", x); }
注意してほしいのが, some関数が引数で受け取る値はVector
Mutable参照
&mut T を用いることでMutable参照を実現する. この実装によってリソースの変更が可能で, 副作用を持たせることが出来る.
fn main() { let mut x = 2; { let y = &mut x; *y = 6; } println!("{}", x); }
外側のスコープで宣言したxを &mut 参照を用いてyに引き渡している. アスタリスクを引き渡したyに追加することで, 参照内容であるxにアクセスすることが出来る. 即ちxの値を書き換えることが出来る.