在查看 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
子句,通过采用导致代码 mutating 的路径,就可以返回提到的借用v
。
我错了吗?当允许这样的代码会导致问题时,谁能举个例子?