generated at
値のowner

その値のownershipを誰が持っているのか


これって何を持って判断するの?
例えば、IDEのhintで教えてくれたりしない?
syntaxを見てわかるでしょ、という知識的なもの?



例題
rs
let p1 = Parent(1, Child(11), Child(12));
Child(11) Child(12) のownerは誰か?
Parent
Parent のownerは誰か?
p1


例題
rs
fn main() { let s1 = String::from("hello"); // 1 let s2 = s1; // 2 println!("{}", s2); // 3 } // 4
1~4のそれぞれの行において、値 String::from("hello") のownerは誰か?
1. s1
2. s2
4. s2がスコープを抜けるので、ownerは破棄される


例題
rs
fn main() { let s1 = String::from("hello"); // 1 let s2 = &s1; // 2 println!("{}", s2); // 3 } // 4
1~4のそれぞれの行において、値 String::from("hello") のownerは誰か?
1. s1
2. s1
3. s1
4. s1がスコープを抜けるので、ownerは破棄される

例題
rs
fn main() { let mut s1 = String::from("hello"); // 1 let s2 = &mut s1; // 2 s2.push_str(" world"); // 3 println!("{}", s1); // 4 }
1~4のそれぞれの行において、値 String::from("hello") のownerは誰か?
1. s1
2. s1
3. s1
4. s1
また、 s2 の借用のスコープが終了するタイミングはいつか?
3. mutable参照は最後に使用された時点で終了する。そのため、4でs1を使用できている。
例えば、4の後に、に3と同じ内容の文を追記すればエラーになる。


例題
rs
fn main() { let s1 = String::from("hello"); // 1 takes_ownership(s1); // 2 // println!("{}", s1); // 3 エラーになる行 } fn takes_ownership(s: String) { // 5 println!("{}", s); // 6 } // 7
以下のそれぞれの行において、値 String::from("hello") のownerは誰か?
1. s1
2. takes_ownership (の引数s)にmoveする
5. takes_ownership内の引数sがowner
6. takes_ownership内の引数sがowner
7. 破棄される. takes_ownershipのスコープが終了し、sがスコープを抜けるため。値はmainに戻ってこない。
また、3行目のコメント部分を有効化した場合のエラーの原因を説明せよ
takes_ownershipにmoveするため、s1は未初期化状態になっているから。


例題
rs
fn main() { let s1 = String::from("hello"); // 1 let s2 = takes_and_returns(s1); // 2 println!("{}", s2); // 3 } fn takes_and_returns(s: String) -> String { // 5 s // 6 } // 7
以下のそれぞれの行において、値 String::from("hello") のownerは誰か?
1. s1
2. takes_and_rerutnsの引数sにmoveし、関数の返り値として同じ値がs2にmoveする
3. s2
5. takes_and_returnsの引数s
6. s. 返却される値として所有権がmoveする準備がされる
7. sの所有権が返却され、スコープ外に破棄されずmainにmoveする
また、 takes_and_returns で値が返却される際の所有権の移動を説明せよ
元の値sのownershipがそのままmainに返却される
新しい値は作成されず、元の値がそのままmoveする。新しいメモリ割り当ては発生しない。



例題
rs
fn main() { let s1 = String::from("hello"); // 1 let s2 = String::from("world"); // 2 let result = longest(&s1, &s2); // 3 println!("{}", result); // 4 } // 5 fn longest(x: &str, y: &str) -> &str { if x.len() > y.len() { x } else { y } }
以下のそれぞれの行において、値 String::from("hello") String::from("world") のownerは誰か?
1. hello: s1
2. world: s2
3. hello/world共に参照を渡すのでmoveは発生しない
4. hello/world共にs1とs2が所有。resultはborrowした参照を保持
5. hello/world共にスコープ終了時にs1とs2が破棄される
また、 longest の返り値のlifetimeがどうなるか説明せよ
longest の返り値のlifetimeは、引数 x,yのlifetimeの短い方に依存する。
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {...}


例題
rs
fn main() { let s1 = String::from("hello"); // 1 match s1 { // 2 s if s == "hello" => { // 3 println!("Matched: {}", s); // 4 } _ => println!("No match"), // 5 } // 6 }
以下のそれぞれの行において、値 String::from("hello") のownerは誰か?
1. s1
2. match. s1の所有権がmatchにmoveする
3. s. s1の所有権がパターン変数sにmoveする
4. sのまま
5. ここには到達しないが、s以外のパターンでは所有権は破棄される
6. パターン変数sのスコープが終了するので、値は破棄される