Rust lifetime问题:修改示例代码后未出现预期悬垂引用错误?
Rust生命周期现象底层原因解析
- 你观察到的运行正常的现象本质是字符串字面量的特殊生命周期属性导致的,和你对普通引用生命周期的直觉认知并不冲突。
- Rust中双引号直接声明的字符串字面量(如
"rust"、"ecmascript")会被编译进二进制文件的只读数据段,程序运行全程不会释放该部分内存,对应类型为&'static str,生命周期'static代表其存活时间覆盖程序整个运行周期。 - 你代码中内部作用域声明的
s1、s2本身是栈上的临时变量,作用域结束后确实会被回收,但它们存储的值是指向静态数据段的&'static str引用,而非指向栈内存的地址。你将该引用赋值给r时,拷贝的是指向静态数据的引用本身,因此即使内部作用域销毁,r持有的引用仍然指向合法的静态内存,不会成为悬垂引用。 - 你可以通过如下代码验证普通引用的生命周期规则,代码会直接在编译期抛出悬垂引用错误:
fn longer<'a>(s1: &'a str, s2: &'a str) -> &'a str { if s2.len() > s1.len() { s2 } else { s1 } } fn main() { let r; { // 改为堆上分配的String类型,生命周期绑定到当前作用域 let s1 = String::from("rust"); let s2 = String::from("ecmascript"); r = longer(&s1, &s2); } // 此处访问r时s1、s2已被销毁,对应堆内存已释放,编译报错 println!("{} is longer", r); }
内容的提问来源于stack exchange,提问作者ChrisFisher
相关产品推荐
相关产品推荐

