假设函数返回对局部变量的悬空引用:
fn foo<'a>() -> &'a i32 {
let i = 2;
&i
}
fn main() { }
Rust 注意到这一点并引发错误。
我的问题是为什么它在不使用
foo
的情况下执行此操作?我会理解如果 main
是
fn main() {
let i_ref = foo();
}
那么会引发错误,因为
'a
无法转换为i_ref
的生命周期,因为前者不完全包含后者。
如果不在某个时刻调用
foo
,Rust 如何检测这个悬空引用?还是这个案例太简单了,以至于无需采取任何终生行动就能引起注意?或者是否通过其他方式检测到这种错误?
传递给非异步函数的所有生命周期都必须对整个函数体有效 - 对参数的引用在函数执行期间不能自发变得无效。
此规则自动阻止返回本地引用,因为它们的生命周期实际上在函数返回之前结束。
(异步函数有点不同 - 在幕后,它们返回一个不透明的 future 对象,该对象可能保存也可能不保存引用。但它们仍然阻止返回对堆栈分配变量的引用。)
另一种思考方式:
foo<'a>() -> &'a i32
让调用者选择它想要的任何生命周期,只要(不存在的)参数的生命周期与返回值匹配。我可以想象调用 foo::<'static>()
,根据函数签名的规则,它必须被接受,但显然对于返回局部变量的函数来说是无效的。