Rust を見ていると、よくわからない動作に気付きました。
私は期待通りに動作するこのコードを持っています:
fn get_or_create_foo(v: &mut Vec<String>) -> String {
match v.get(0) {
Some(x) => return x.clone(),
None => ()
}
println!("creating foo");
v.push("foo".to_string());
v.get(0).unwrap().clone()
}
fn main() {
let mut v = Vec::new();
println!("{}", get_or_create_foo(&mut v));
println!("{}", get_or_create_foo(&mut v));
}
get_or_create_foo()
借用した文字列スライスを返すように変更すると、コンパイラはコンパイルを拒否します。
fn get_or_create_foo(v: &mut Vec<String>) -> &str {
match v.get(0) {
Some(x) => return x,
None => ()
}
println!("creating foo");
v.push("foo".to_string());
v.get(0).unwrap()
}
コンパイル ログ:
$ rustc --verbose src/main.rs
src/main.rs:8:5: 8:6 error: cannot borrow `*v` as mutable because it is also borrowed as immutable
src/main.rs:8 v.push("foo".to_string());
^
src/main.rs:2:11: 2:12 note: previous borrow of `*v` occurs here; the immutable borrow prevents subsequent moves or mutable borrows of `*v` until the borrow ends
src/main.rs:2 match v.get(0) {
^
src/main.rs:10:2: 10:2 note: previous borrow ends here
src/main.rs:1 fn get_or_create_foo(v: &mut Vec<String>) -> &str {
...
src/main.rs:10 }
^
error: aborting due to previous error
私の理解では、コードは有効です。前述の借用はmatch
、コードの変更につながるパスを使用して制御が句を離れるとすぐに返される可能性がありますv
。
私が間違っている?そのようなコードを許可すると問題が発生する場合、誰かが例を挙げてもらえますか?