Rust生命周期参数语义疑问:返回值生命周期约束表述是否有误?
结论
你的理解完全正确,官方书籍的表述属于措辞歧义,混淆了生命周期注解的约束方向。
具体解释
我们先明确生命周期标注'a的实际推导逻辑:
- 对
longest函数的签名,编译器会先取两个入参x、y实际生命周期的交集作为'a的具体取值,也就是说'a的长度天然等于两个入参生命周期中更短的那一个。 - 标注在返回值上的
&'a str,约束的是返回值的存活时长不能超过'a的范围,也就是你说的“返回的字符串切片的生命周期至多等于'a”。
原书的表述错误根源在于,它把入参引用的约束规则套用到了返回值上:
- 对入参的
&'a str来说,要求的是“被引用的字符串的生命周期至少等于'a”,这是为了保证入参引用本身在'a范围内是有效的,不会悬垂。 - 但对返回值的
&'a str来说,约束的是使用者拿到返回值后的使用范围:不能让返回值活的比'a久,否则就会出现返回值还在使用,但它指向的入参已经被释放的悬垂问题。
如果按原书的说法,所有参数和返回值的生命周期都“至少等于'a”,编译器确实可以把'a设为空作用域来满足所有条件,生命周期注解就完全失去了检查悬垂引用的作用,和实际的编译规则完全不符。
我们可以用一段代码验证实际规则:
fn main() { let result; let string1 = String::from("abcd"); { let string2 = String::from("xyz"); result = longest(string1.as_str(), string2.as_str()); } // string2在此处释放,两个入参的生命周期交集'a到此结束 println!("The longest string is {}", result); // 编译器直接报错:result存活时间超过了'a的范围 }
这段代码的报错恰恰验证了你的判断:返回值的生命周期不能超过'a,也就是至多等于'a。
内容的提问来源于stack exchange,提问作者nalzok
相关产品推荐
相关产品推荐

