Rust栈上字符串切片的生命周期困惑:为何该代码可编译?
为什么
main2能编译,main1却不行? 关键区别:字符串字面量的生命周期是'static
先看两个例子里string2的本质差异:
main1里的string2是String::from("xyz")创建的动态字符串对象,它的生命周期只限于内部代码块,代码块结束后就会被销毁,对应的切片自然也失效了。main2里的"xyz"是字符串字面量,它会被直接编译进程序的二进制文件,属于静态数据,生命周期是'static——从程序启动到终止全程存在,不会因为代码块结束而消失。
关于longest函数的生命周期匹配
longest的签名要求两个输入引用的生命周期都至少覆盖同一个'a,返回值的生命周期也是'a:
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str { if x.len() > y.len() { x } else { y } }
在main2的场景中:
string1.as_str()的生命周期是从string1创建到main函数结束"xyz"的'static生命周期完全覆盖了前者的生命周期
编译器会把'a推断为string1的生命周期——因为长生命周期的引用可以自动转换成短生命周期的引用,满足&'a str的约束。这样返回值的生命周期就和string1一致,result在main函数后续的println!中依然有效,所以编译通过。
你疑惑为什么longest没返回更短的生命周期?因为编译器会选择满足所有约束的最长可能生命周期,这里'static足够长,所以可以匹配到string1的生命周期,而不是内部代码块的短生命周期。如果两个输入的生命周期都很短(比如main1里的情况),那编译器才会被迫用那个短生命周期,导致后续引用失效报错。
结论:"xyz"的内存绝对有效
字符串字面量属于程序的静态内存区域,只要程序在运行,它就一直存在,完全不用担心代码块结束后内存被释放的问题。哪怕你直接把代码改成下面这样,也能正常编译:
fn main() { let string1 = String::from("abcd"); let result = longest(string1.as_str(), "xyz"); println!("The longest string is {}", result); }
内容的提问来源于stack exchange,提问作者May
相关产品推荐
相关产品推荐

