Rust如何在没有使用函数的情况下检测对局部变量的引用?

li9yvcax  于 12个月前  发布在  其他
关注(0)|答案(1)|浏览(112)

假设一个函数返回一个对局部变量的悬空引用:

fn foo<'a>() -> &'a i32 {
    let i = 2;
    &i
}

fn main() { }

字符串
Rust注意到了这一点,并引发了一个错误。
添加寿命:

fn foo<'a>() -> &'a i32 {
    'b: {
        let i = 2;          // i has lifetime 'b
        &'c i
    }
}


Rust推断'c = 'b,因为&i引用i。此外,'a被示例化为'c,因此'b,因为返回类型是&'a i32,返回值是&'c i32。我不明白为什么这里会发生错误,因为所有生命周期都可以用具体值示例化,而不会有任何不匹配。
如果main

fn main() {
    'd: {
        let i_ref: &'d i32 = foo();    // foo() has lifetime 'b
    }
}


那么我们仍然会有'a = 'c = 'b,但是在main中有一个生命周期不匹配,因为'b不包含'd。在这种情况下,我会期望一个错误。
在第一种情况下,Rust是如何在没有调用foo的情况下检测到悬空引用的?

arknldoa

arknldoa1#

所有传递给非Java函数的生命周期必须对整个函数体有效-生命周期不能在函数执行期间自发存在或无效。
此规则自动排除返回局部引用,因为它们的生存期实际上正好在函数返回之前结束。
(异步函数有点不同--在后台,它们返回一个不透明的未来对象,可能包含也可能不包含引用。但它们仍然阻止返回对堆栈分配变量的引用。)
换一种方式思考:
foo<'a>() -> &'a i32让调用者选择它想要的任何生存期,只要(不存在的)参数的生存期与返回值匹配。我可以想象调用foo::<'static>(),根据函数签名的规则,它必须被接受,但显然对于返回局部变量的函数无效。

相关问题