使用 string.replace() 时"Temporary value dropped while borrowed"



有人能解释一下删除了哪个确切的临时值,以及建议的执行此操作的方法是什么吗?

fn main() {
let mut a = &mut String::from("Hello Ownership");
a = &mut a.replace("Ownership", "World");
println!("a is {}", a);
}

如果你想保留&mut引用(当然,在你的情况下通常不需要(,你可以这样做:

fn main() {
let a = &mut String::from("Hello Ownership");
let a = &mut a.replace("Ownership", "World");
println!("a is {}", a);
}

CCD_ 2的类型将由CCD_。在第二行中,我们做了变量阴影(不是必需的(,类型仍然是&mut String

这并不能完全回答你的问题我不知道为什么你的版本没有编译,但至少我认为这些信息可能有用(见下文(

更新

多亏了Solomon的发现,我想补充一下,在这种情况下:

let a = &mut ...;
let b = &mut ...;

或者这个(变量阴影,基本上与上面相同(:

let a = &mut ...;
let a = &mut ...;

,编译器将自动延长每个临时的生存期,直到封闭块结束。但是,在以下情况下:

let mut a = &mut ...;
a = &mut ...;

,编译器似乎根本不做这样的生存期扩展,所以这就是为什么OP的代码不编译,尽管代码似乎在做几乎相同的事情。

为什么在那里使用&mut?试试这个:

fn main() {
let mut a = String::from("Hello Ownership");
a = a.replace("Ownership", "World");
println!("a is {}", a);
}

啊哈,想通了!

https://doc.rust-lang.org/nightly/error-index.html#E0716说:

临时语句并不总是放在封闭语句的末尾。在简单的情况下;表达式立即存储到一个变量中,编译器将自动延长临时的生存期,直到封闭块结束。因此,修复原始程序的另一种方法是写入let tmp = &foo()而不是let tmp = foo():

fn foo() -> i32 { 22 }
fn bar(x: &i32) -> &i32 { x }
let value = &foo();
let p = bar(value);
let q = *p;

在这里,我们仍然借用foo((,但由于借位是直接分配到变量中的,所以临时的直到封闭块结束才会被删除。当临时存储到元组或结构等聚合结构中时,类似的规则也适用:

// Here, two temporaries are created, but
// as they are stored directly into `value`,
// they are not dropped until the end of the
// enclosing block.
fn foo() -> i32 { 22 }
let value = (&foo(), &foo());

相关内容

最新更新