为何这段返回局部变量引用的Rust函数能通过编译?
为什么这段返回局部变量引用的Rust函数能编译通过?
你猜的没错,硬编码的字符串字面量在Rust里确实是特殊处理的,核心原因在于它的生命周期和存储位置:
1. 字符串字面量的本质
像"default"这种字符串字面量,不是在函数栈上临时分配的——编译器会把它直接打包进程序的二进制文件的只读数据段里,从程序启动到结束一直存在。所以指向它的引用&str拥有'static生命周期,也就是全局生命周期,永远不会失效。
2. 拆解你的代码
你代码里的let default: &str = "default";,这个default是栈上的一个变量,但它存的不是字符串本身,而是指向那个静态字符串的引用(也就是&'static str)。
3. 为什么返回引用不会报错?
如果你的代码里是返回default(可能你写的&default是笔误?),这完全符合规则:
- 函数输入的
input_str是一个带有局部生命周期'a的&str,而default是&'static str。Rust的生命周期推断会自动把函数返回值的生命周期统一为'a——因为'static比任何局部生命周期都长,把它“缩短”成'a是安全的,相当于告诉编译器:返回的引用至少能活到和输入参数一样久。
如果真的是返回&default(指向栈上变量default的引用),理论上应该报错,因为default是函数内的栈变量,函数结束就会销毁。但能编译通过的话,大概率是编译器做了优化——它看穿了default里存的是'static引用,直接把&default优化成了指向静态字符串的引用,相当于绕开了栈变量的生命周期限制。
4. 和普通局部变量的区别
比如你如果写let default = String::from("default");再返回&default,肯定会报错——因为这个default是栈上的String实例,函数结束就被销毁了,返回它的引用就是悬垂引用,这正是Rust要拦的危险操作。而字符串字面量根本不存在这个问题,它的存储位置不在栈上,生命周期是全局的。
内容的提问来源于stack exchange,提问作者Kami SM
相关产品推荐
相关产品推荐

