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

时间:2017-03-30 02:25:21

标签: scope rust

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

fn main() {
    let a = "a";
    let v;
    {
        let b = "b";
        v = &b;
    }
    println!("{}", v);
}

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

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

fn main() {
    let a = "a";
    let v;
    {
        let b = "b";
        v = getRef(&b);
    }
    println!("{}", v);
}

问题是,v仍然是对b的引用,而b超出了println!()的范围。

为什么这两者不同?

1 个答案:

答案 0 :(得分:5)

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

如果您print the type of the variable,您会在第一个示例中看到v类型为&&str,具体为& &'static str。在第二个示例中,v的类型为&str,具体为&'static str

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

在第二个示例中,虽然您引用b,生成&&str,然后调用期望&str的函数。 Deref coercion启动并自动取消引用该值。

因此第二个例子相当于

fn main() {
    let a = "a";
    let v;
    {
        let b = "b";
        v = b;
    }
    println!("{}", v);
}

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