第一个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!().
为什么这两个不同?
因为他们没有做同样的事情.
如果您打印变量的类型,您将在第一个示例中看到,具体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)
也就是说,您正在复制一个字符串的不可变引用,该字符串将在程序的整个生命周期中存在.