gpt4 book ai didi

rust - 为什么我可以重新分配给 move 的变量?

转载 作者:行者123 更新时间:2023-12-03 11:25:51 25 4
gpt4 key购买 nike

我发现这段代码可以编译:

let mut s1 = String::from("hello");
let _s2 = s1;
s1 = String::from("world");
println!("{}", s1);

如果没有第三行,我会得到一个错误,提示不能借用 move 的变量,这对我来说是可以理解的:

error[E0382]: borrow of moved value: `s1`
--> src/main.rs:5:16
|
2 | let mut s1 = String::from("hello");
| ------ move occurs because `s1` has type `std::string::String`, which does not implement the `Copy` trait
3 | let _s2 = s1;
| -- value moved here
4 | //s1 = String::from("world");
5 | println!("{}", s1);
| ^^ value borrowed here after move

第三行,代码编译。

我的理解是:s1被 move 后,s1仍然处于某种有效状态,只是编译器阻止了你访问它;如果您重新分配它,它会获得新的所有权,并且编译器会理解它,因此它会编译。

我说的对吗?我在哪里可以找到任何对此进行正式解释的文档/规范?

最佳答案

s1 的原始值已 move ,因此尝试使用 s1 是非法的 - 直到它被赋予新值为止。

Here's my understanding: after s1 is moved, s1 is still in some kind of valid state, it's just the compiler that prevents you from accessing it; if you re-assign it, it gets new ownership, and the compiler understands it so it compiles.

无效。当 s1 被 move 时,绑定(bind)现在是未初始化的内存,所以使用它是非法的。给它一个新的值意味着内存不再是未初始化的,可以安全地再次使用。

与以下比较:

let mut s1; 
s1 = String::from("world");
println!("{}", s1);

在第一行,s1 与在您的原始代码中 move 后的状态完全相同。

请注意,编译器可能会选择为第二个值使用不同的内存地址。不允许对原始值的引用在 move 之后继续存在,因此除非您开始打印原始指针,否则此实现细节是完全不可观察的。

您可能会由此推断,重新分配给 move 的可变绑定(bind)在语义上等同于引入一个隐藏第一个绑定(bind)的新绑定(bind)。这几乎是真的,但不完全是。删除绑定(bind)的顺序与引入绑定(bind)的顺序相反,此处的删除顺序反射(reflect)了原始绑定(bind)的顺序。

关于rust - 为什么我可以重新分配给 move 的变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64358363/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com