第一个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 str
v
&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)
也就是说,您正在复制一个字符串的不可变引用,该字符串将在程序的整个生命周期中存在.