tao*_*tsi 3 move-semantics rust
我发现这段代码编译:
let mut s1 = String::from("hello");
let _s2 = s1;
s1 = String::from("world");
println!("{}", s1);
Run Code Online (Sandbox Code Playgroud)
如果第三行不存在,我会收到一个错误,抱怨不能借用移动的变量,这对我来说是可以理解的:
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
Run Code Online (Sandbox Code Playgroud)
第三行,代码编译。
这是我的理解:s1移动后,s1仍然处于某种有效状态,只是编译器阻止您访问它;如果您重新分配它,它将获得新的所有权,并且编译器会理解它以便进行编译。
我对吗?我在哪里可以找到任何正式解释这一点的文档/规范?
的原始值s1已移动,因此尝试使用是非法的s1- 直到它被赋予新值为止。
这是我的理解:
s1移动后,s1仍然处于某种有效状态,只是编译器阻止您访问它;如果您重新分配它,它将获得新的所有权,并且编译器会理解它以便进行编译。
它无效。当 as1被移动时,绑定现在是未初始化的内存,因此使用它根本是非法的。给它一个新值意味着内存不再未初始化并且可以安全地再次使用。
与以下内容进行比较:
let mut s1;
s1 = String::from("world");
println!("{}", s1);
Run Code Online (Sandbox Code Playgroud)
在第一行,s1与在原始代码中移动后的状态完全相同。
请注意,编译器可能会选择为第二个值使用不同的内存地址。对原始值的引用不允许在移动之后继续存在,因此除非您开始打印原始指针,否则此实现细节是完全不可观察的。
您可能由此推断,重新分配给移动的可变绑定在语义上等同于引入一个新的绑定来掩盖第一个绑定。这几乎是正确的,但不完全正确。绑定被删除的顺序与它们被引入的顺序相反,这里的删除顺序反映了原始绑定的顺序。
| 归档时间: |
|
| 查看次数: |
92 次 |
| 最近记录: |