为何将&mut Vec<&'static str>传入接受&mut Vec<&'a str>的Rust函数可编译?
问题解答
为什么你的代码能正常编译?
Rust编译器会自动推导my_func中生命周期参数'a的具体值。在你的代码里,编译器直接将'a推导为'static,此时函数参数类型&mut Vec<&'static str>和你传入的&mut b类型完全一致——根本没有发生任何类型转换,自然不会违反&mut T的不变性规则,所以编译可以通过。
书中描述的编译失败场景示例
书中说的情况是:当你试图把&mut Vec<&'static str>当作&mut Vec<&'a str>('a是一个比'static更短的生命周期)使用时,&mut T的不变性会阻止这种转换,导致编译失败。以下是符合该场景的代码:
fn my_func<'a>(_a: &mut Vec<&'a str>, _short_lived: &'a str) { // 如果允许编译,这里可以向Vec中添加短生命周期的引用 // _a.push(_short_lived); } fn main() { let inner: &'static str = "foo"; let mut b: Vec<&'static str> = vec![inner]; // 创建一个短生命周期的字符串 let short_str = String::from("bar"); let short_ref = &short_str; // 尝试传入&mut b和short_ref,此时'a会被推导为short_str的生命周期 my_func(&mut b, short_ref); // 编译错误! }
编译错误信息(简化版)
error[E0308]: mismatched types --> src/main.rs:12:13 | 12 | my_func(&mut b, short_ref); | ^^^^^^ expected `&mut Vec<&str>`, found `&mut Vec<&'static str>` | = note: expected mutable reference `&mut Vec<&'a str>` found mutable reference `&mut Vec<&'static str>`
错误原因
&mut T在T上是不变量,意味着即使Vec<&'static str>和Vec<&'a str>看起来有生命周期包含关系,也不能互相转换。如果允许这种转换,my_func就可以向原本存储&'static str的b中添加短生命周期的short_ref,当short_str被销毁后,b里就会出现悬垂引用,这正是Rust的生命周期系统要避免的安全问题。
内容的提问来源于stack exchange,提问作者ignoring_gravity
相关产品推荐
相关产品推荐

