gpt4 book ai didi

rust - 为什么在指针移动后分配给指针的成员仍然有效?

转载 作者:行者123 更新时间:2023-11-29 07:42:17 26 4
gpt4 key购买 nike

为什么 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));
}

以下编译时不会出现熟悉的“使用移动值”错误:

#[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
};
}
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

最佳答案

这与是否是指针没有任何关系;这也适用:

#[derive(Debug)]
struct NonCopy;

#[derive(Debug)]
struct Example {
name: NonCopy,
}

fn main() {
let mut foo = Example {
name: NonCopy,
};

drop(foo);

foo.name = NonCopy;
}

虽然我找不到我以前见过的类似 SO 问题,但是这个 quote from nikomatsakis描述它:

In general moves are tracked at a pretty narrow level of granularity. We intend to eventually permit you to "fill" both fields back in and then use the structure again. I guess that doesn't work today. I have to go look again at the moves code, but I think in general one of the things I'd like to pursue post 1.0 is extending the type system to deal better with things that have been moved from (in particular I want to support moves out of &mut pointers, so long as you restore the value before doing anything fallible). Anyway I think this example more-or-less falls out of treating things in a general way, though you could imagine rules that say "if you move f, you can never again touch any subfields of f without restoring f as a unit".

还有关于 the Rust subreddit 的讨论, 链接到 Rust issue 21232: "borrow-checker allows partial reinit of struct that has been moved away, but no use of it"

从概念上讲,除了结构本身之外,结构中的每个字段都有一个标志 — 我喜欢想到 Chris Morgan's cardboard box analogy .只要在使用结构之前移回,就可以移出拥有的结构的字段:

drop(foo.name);
foo.name = NonCopy;

println!("{:?}", foo);

显然,自 2014 年以来,没有人愿意在重新填充字段后再次将整个结构标记为有效。

实际上,您并不真正需要此功能,因为您可以一次分配整个变量。当前的实现过于安全,因为 Rust 会阻止您做一些看似正常的事情。

关于rust - 为什么在指针移动后分配给指针的成员仍然有效?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46833271/

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