为何Rust中生命周期约束不匹配却未报告编译错误?
问题原因解析
你这里的核心误解是泛型生命周期参数并非直接绑定到变量的生命周期,而是编译器会根据调用场景和约束条件,为这些参数推断出合适的具体生命周期,只要满足所有给定的约束即可。
具体拆解你的代码逻辑:
- 函数约束
'long: 'longest的实际含义是:'long代表的生命周期必须至少和'longest一样长(即'long的存活时间不短于'longest)。 - 在
main函数中,三个变量的实际生命周期长度是:longest(最外层)>longer(中间块)>long(最内层)。
当调用test_lifetime时,编译器并没有强制把'longest绑定到longest变量的生命周期,而是做了这样的灵活推断:
- 将泛型参数
'long推断为long变量的生命周期(三个里最短的那个) - 将泛型参数
'longest也推断为long变量的生命周期 - 此时
'long: 'longest的约束自然成立(同一个生命周期肯定满足“不短于”的要求) - 对于
c参数(原本是longest的引用,生命周期最长),Rust允许将更长的生命周期引用强制转换为更短的生命周期引用(因为长生命周期包含短生命周期,操作安全合法),所以&'longest_var str可以被当作&'long_var str传入。
所有约束都被满足,因此编译器不会报错。
如果想要触发编译错误,你需要让编译器无法通过缩小生命周期范围来满足约束。比如修改函数,强制要求'longest必须覆盖到更长的代码范围:
fn test_lifetime<'long, 'longer, 'longest>(a: &'long str, b: &'longer str, c: &'longest str) -> &'longest str where 'long: 'longest, 'longer: 'longest { if true { c } else { a } } fn main() { let longest = String::from("longest"); let result; { let longer = String::from("longer"); { let long = String::from("long"); result = test_lifetime(long.as_str(), longer.as_str(), longest.as_str()); } } println!("{}", result); }
这段代码会报错,因为result的生命周期被绑定到'longest,而约束要求'long: 'longest,意味着'longest不能超过long变量的生命周期,但result在long销毁后仍被使用,违反了生命周期安全规则。
内容的提问来源于stack exchange,提问作者Anunaki
相关产品推荐
相关产品推荐

