我最近正在学习所有权和生命周期。但我发现字符串文字有一个奇怪的情况。
//! work perfectly
fn foo() -> &'static str {
let a = "66";
&a
}
fn main() {
let b = foo();
println!("{}", b);
}
Run Code Online (Sandbox Code Playgroud)
当我像上面一样使用字符串文字时,它工作得很好。但是当我像下面这样使用它时:
//! broken
fn main() {
{
let b;
{
let a = "66";
b = &a;
}
println!("{}", b);
}
}
Run Code Online (Sandbox Code Playgroud)
它坏了,告诉我:
b = &a;
^^ borrowed value does not live long enough
Run Code Online (Sandbox Code Playgroud)
这些让我很困惑。为什么它们不同?
这两个程序之间的差异来自于自动取消引用。
//! work perfectly
fn foo() -> &'static str {
let a = "66";
&a // the type of this expression is not &'static str it is &&'static str
}
fn main() {
let b = foo();
println!("{}", b);
}
Run Code Online (Sandbox Code Playgroud)
由于 的类型a是&'static str的类型&a是&&'static str。请注意第二个参考。它是对没有静态生存期的字符串的引用,而不是字符串值。但是,由于foo返回类型为&'static str,&a因此自动取消引用a,并且 的类型b被推断为&'static str。在第二个程序中,这种情况不会发生,因为类型不明确,因此 b 被推断为 a,&&'static str它引用的引用仅在块的生命周期内有效。
如果更新第二个程序以显式声明 b 的类型,您将获得相同的效果。
然而,更好的方法是完全不依赖自动取消引用,并使用以下两个程序之一:
fn foo() -> &'static str {
let a = "66";
a // note no &
}
fn main() {
let b = foo();
println!("{}", b);
}
Run Code Online (Sandbox Code Playgroud)
或者
fn main() {
{
let b;
{
let a = "66";
b = a; // Again no &
// In idiomatic code it would probably make sense to inline the
// assignment, but I have left it in for clarity with the original code
}
println!("{}", b);
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
121 次 |
| 最近记录: |