在Rust中看似矛盾的借阅场景

Aar*_*onF 3 scope rust

第一个Rust程序将无法编译,因为b它在引用之前被删除r,这是有道理的:

fn main() {
    let a = "a";
    let v;
    {
        let b = "b";
        v = &b;
    }
    println!("{}", v);
}
Run Code Online (Sandbox Code Playgroud)

在第二个Rust程序中,b通过函数检索引用,突然之间没有问题:

fn getRef(b: &str) -> &str {
    b
}

fn main() {
    let a = "a";
    let v;
    {
        let b = "b";
        v = getRef(&b);
    }
    println!("{}", v);
}
Run Code Online (Sandbox Code Playgroud)

问题是,v仍然是一个参考b,并且b超出范围println!().

为什么这两个不同?

She*_*ter 5

因为他们没有做同样的事情.

如果您打印变量的类型,您将在第一个示例中看到,具体v是类型.在第二个例子中,具体是类型.&&str& &'static strv&str&'static str

在第一个示例中,您具有对本地值的引用,该值实际上超出了范围.

在第二个例子中,虽然你引用了b一个&&str,然后生成一个,然后调用一个期望a的函数&str.Deref胁迫开始并自动取消引用该值.

因此第二个例子相当于

fn main() {
    let a = "a";
    let v;
    {
        let b = "b";
        v = b;
    }
    println!("{}", v);
}
Run Code Online (Sandbox Code Playgroud)

也就是说,您正在复制一个字符串的不可变引用,该字符串将在程序的整个生命周期中存在.