fn func_vecmut<'a>(v: &'a mut Vec<&'a i32>, s: &'a String) {}
fn func_vecmut_fresh_lf<'a, 'b>(v: &'a mut Vec<&'a i32>, s: &'b String) {}
fn func_vec<'a>(v: &'a Vec<&'a i32>, s: &'a String) {}
fn main() {
let mut v = vec![];
{
let s: String = String::from("abc");
/* Note: Below, only one function call is active at a time, other two commented out */
func_vecmut(&mut v, &s); // Understandably, compiler fails this.
func_vecmut_fresh_lf(&mut v, &s); // Understandably, compiler passes this i.e with fresh lifetime for String.
func_vec(&v, &s); // Why does compiler pass this?
}
}
在func_vecmut
中(据我所知),编译器发现String
的生命周期与Vec
的生命周期和它所拥有的元素(i32
)相同。并且由于v
的寿命更长(在块外定义),它会将借位扩展到s
超出块的范围(即s
的来世),因此会出现以下错误:
error[E0597]: `s` does not live long enough
--> src/main.rs:13:30
|
13 | func_vecmut(&mut v, &s); // Understandably, compiler fails this.
| ^ borrowed value does not live long enough
...
16 | }
| - `s` dropped here while still borrowed
17 | }
| - borrowed value needs to live until here
可以通过为String
参数赋予新的生命周期来解决问题(参见func_vecmut_fresh_lf
)。
但是,为什么func_vec(&v, &s)
的编译不会失败?唯一的区别是&mut Vec
。这与不可变引用是Copy
这一事实有关,而可变引用则不是这样吗?如果是的话,怎么样?函数体是空的,编译器在这里推断出什么?