首页 文章

为什么我可以返回对本地文字的引用而不是变量?

提问于
浏览
13

为什么这段代码会编译?

fn get_iter() -> impl Iterator<Item = i32> {
    [1, 2, 3].iter().map(|&i| i)
}

fn main() {
    let _it = get_iter();
}

[1, 2, 3] 是一个局部变量, iter() 借用它 . 此代码不应编译,因为返回的值包含对局部变量的引用 .

1 回答

  • 18

    在您的示例中, [1, 2, 3] 不被视为局部变量,而是静态变量!

    我们来看看这段代码:

    fn foo() -> &'static [i32] {
        &[1, 2, 3]
    }
    

    这有效!

    前段时间,RFC 1414: Rvalue Static Promotion被合并:"Promote constexpr rvalues to values in static memory instead of stack slots" . 这意味着你写的基本上所有文字都可以永远存在 . 因此, let _: &'static i32 = &42; 之类的东西也有效!

    如果我们避免使用文字数组,我们可以看到预期的错误:

    fn bar() -> impl Iterator<Item = i32> {
        vec![1, 2, 3].iter().map(|&i| i)
    }
    

    在这里,我们得到“ v 不够长寿”的错误 .

    这不仅限于整数或数组;它广泛适用:

    fn promote_integer() -> &'static i32 {
        &42
    }
    
    fn promote_float() -> &'static f64 {
        &42.42
    }
    
    fn promote_char() -> &'static char {
        &'c'
    }
    

相关问题