第一个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!()
的范围。
为什么这两者不同?
答案 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);
}
也就是说,您正在复制一个字符串的不可变引用,该字符串将在程序的整个生命周期中存在。