为什么n1_mut在这个例子中仍然有效?它已经被移入,Option::Some所以它不应该是无效的吗?
struct MyRecordRec2<'a> {
pub id: u32,
pub name: &'a str,
pub next: Box<Option<MyRecordRec2<'a>>>
}
#[test]
fn creating_circular_recursive_data_structure() {
let mut n1_mut = MyRecordRec2 {
id: 1,
name: "n1",
next: Box::new(None)
};
let n2 = MyRecordRec2 {
id: 2,
name: "n2",
next: Box::new(Some(n1_mut))
};
//Why is n1_mut still valid?
n1_mut.next = Box::new(Some(n2));
}
Run Code Online (Sandbox Code Playgroud)
以下不使用熟悉的"使用移动值"错误编译:
#[test]
fn creating_and_freezing_circular_recursive_data_structure() {
let loop_entry = {
let mut n1_mut = MyRecordRec2 {
id: 1,
name: "n1",
next: Box::new(None),
};
let n2 = MyRecordRec2 {
id: 2,
name: "n2",
next: Box::new(Some(n1_mut)),
};
n1_mut.next = Box::new(Some(n2));
n1_mut
};
}
Run Code Online (Sandbox Code Playgroud)
error[E0382]: use of moved value: `n1_mut`
--> src/main.rs:44:9
|
39 | next: Box::new(Some(n1_mut)),
| ------ value moved here
...
44 | n1_mut
| ^^^^^^ value used here after move
|
= note: move occurs because `n1_mut` has type `MyRecordRec2<'_>`, which does not implement the `Copy` trait
Run Code Online (Sandbox Code Playgroud)
这与指针没有任何关系; 这也有效:
#[derive(Debug)]
struct NonCopy;
#[derive(Debug)]
struct Example {
name: NonCopy,
}
fn main() {
let mut foo = Example {
name: NonCopy,
};
drop(foo);
foo.name = NonCopy;
}
Run Code Online (Sandbox Code Playgroud)
虽然我找不到我之前见过的类似SO问题,但nikomatsakis的这句引言描述了它:
通常,移动以非常窄的粒度级别进行跟踪.我们打算最终允许您"填充"两个字段,然后再次使用该结构.我想这在今天不起作用.我必须再看一下移动代码,但我认为总的来说,我想要追求1.0版的一个原因是扩展类型系统以更好地处理已经移动的东西(特别是我想支持移出&mut指针,只要你在做任何错误之前恢复该值).无论如何,我认为这个例子或多或少都不会以一般的方式处理事物,尽管你可以想象规则说"如果你移动f,你再也不能触及f的任何子域而不将f恢复为一个单位".
还有关于Rust subreddit的讨论,它链接到Rust 问题21232:"借用检查器允许部分重新启动结构已被移走,但没有使用它"
从概念上讲,除了结构本身之外,结构中的每个字段都有一个标志 - 我喜欢考虑Chris Morgan的纸板盒类比.只要在使用结构之前重新进入,就可以移出拥有的struct的字段:
drop(foo.name);
foo.name = NonCopy;
println!("{:?}", foo);
Run Code Online (Sandbox Code Playgroud)
显然,自2014年以来,没有人愿意在重新填充字段后再次将整个结构标记为有效.
实际上,您并不真正需要此功能,因为您可以立即分配整个变量.当前的实现过于安全,因为Rust阻止你做一些似乎没问题的事情.
| 归档时间: |
|
| 查看次数: |
237 次 |
| 最近记录: |