Rust 中实际移动变量的是什么?

发布于 2025-01-16 01:31:31 字数 803 浏览 1 评论 0原文

我从未尝试过 C、C++、Go 等语言,所以我决定从 Rust 开始,我已经了解了一些堆栈和堆是什么,但是,移动变量的真正含义是什么? 文档说它不是浅拷贝:

...听起来可能像是在进行浅拷贝。但因为 Rust 也会使第一个变量无效,而不是称其为浅拷贝,所以它被称为移动。在此示例中,我们会说 s1 已移至 s2...

例如:

 let s1 = String::from("hello");
 let s2 = s1;

 println!("{}, world!", s1);

文档中提到“无效”时意味着什么。这是否意味着 Rust 使 s1 无效并将 s1 中的值分配给 s2,所以... s1 > 不存在? o 它有什么价值吗?,这主要是我不明白的,它真的能打动它吗?或者内存中 s1 是否还有任何值?

据我所知,这个检查发生在编译时,所以它让我认为 s1 实际上不存在于内存中,只有 s2,因为 s1 确实被移动了到s2

显然,这种情况发生在大小未知的值(即堆中)上。

我希望你能帮助我理解。 :)

I have never experimented with languages like C, C++, Go, etc., and I decided to start with Rust, I already understand a little what the stack and the Heap are, but, what does it really mean by moving a variable, the documentation says that it is not a shallow copy:

... probably sounds like making a shallow copy. But because Rust also invalidates the first variable, instead of calling it a shallow copy, it’s known as a move. In this example, we would say that s1 was moved into s2...

For example:

 let s1 = String::from("hello");
 let s2 = s1;

 println!("{}, world!", s1);

What does the documentation mean when it says "invalidates". Does this mean that Rust invalidates s1 and assigns the value that was in s1 to s2, so... s1 doesn't exist? o Does it have any value?, that's mainly what I don't understand, does it really move it? or is there still any value in s1 in memory?

From what I could understand, this check happens at compile time, so it makes me think that s1 literally doesn't exist in memory and only s2, since s1 was literally moved to s2.

Obviously this happens with values that have an unknown size, that is, in the heap.

I hope you can help me understand. :)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

晨敛清荷 2025-01-23 01:31:31

对于您提出的几乎每个是/否问题,答案都是“是”和“否”。我们可以在两个不同的上下文中回答这个问题:语言的语义,以及编译器对代码的处理方式。

从语义上讲,将值移至 s2 后,将无法再读取 s1。它可以初始化为新的String值,然后再次使用。从某种意义上说,“未初始化”和“移出”实际上是相同的状态,因为您必须先为变量分配一些内容,然后才能使用它。 (它们在编译器给出的消息中有点不同,并且结构的子值可以移动,但不能取消初始化。)

编译器将对此做什么?嗯,这可能取决于许多因素,包括(但不限于)编译器的版本和所选的优化级别。如果编译器愿意,它可以完全消除移动,因此s2实际上只是与s1相同的内存区域的另一个名称。它还可以在堆栈上为 s2 提供自己的内存区域,并将 s1 的内容位块传输到其中。关于编译器功能的任何具体答案都必须通过对编译环境、编译器版本和提供给编译器的标志的完整描述来限定。

显然,这种情况发生在大小未知的值(即堆中的值)上。

任何拥有的(和未固定的)值都可以移动,无论它是否管理堆上的分配。通常,堆分配本身不会移动。指向堆分配的指针被移动到新位置。 (例如,移动 StringVec 不会更改存储实际内容的内存位置。指向该数据的指针只是易手。)

The answer is both yes and no to pretty much every yes/no question you asked. There's two different contexts we can answer this in: the semantics of the language, and what the compiler does with the code.

Semantically, s1 can no longer be read after the value is moved into s2. It can be initialized to a new String value and then used again. In a manner of speaking, "uninitialized" and "moved from" are effectively the same state in that you must assign something to the variable before you can use it. (They are a bit different in the messages that the compiler gives, and in that sub-values of a struct can be moved-from, but can't be uninitialized.)

What will the compiler do with this? Well, that can depend on many factors, including (but not limited to) the version of the compiler and the optimization level selected. If the compiler wishes to, it can completely elide the move and therefore s2 in effect becomes just another name for the same region of memory as s1. It could also give s2 its own region of memory on the stack and blit the contents of s1 into it. Any specific answer about what the compiler does would have to be qualified with a complete description of the compilation environment, compiler version, and the flags given to the compiler.

Obviously this happens with values that have an unknown size, that is, in the heap.

Any owned (and unpinned) value can be moved, regardless of whether it manages an allocation on the heap. Typically, the heap allocation isn't moved itself. The pointer to the heap allocation is moved to its new location. (For example, moving a String or a Vec won't change the memory location where the actual contents are stored. The pointer to that data is just changing hands.)

甜中书 2025-01-23 01:31:31

文档中说“无效”是什么意思?这是否意味着 Rust 使 s1 无效并将 s1 中的值分配给 s2,所以... s1 > 不存在?

这意味着您作为开发人员无法再访问 s1。因此,从您的角度来看,您可以认为 s1 不存在。

有什么价值吗?

不,因为它不存在(从您的角度来看)。

它真的能感动吗?

取决于程序和编译器。从概念上讲,确实如此。

或者s1在内存中还有值吗?

即使不谈论移动,一般来说变量可能永远不会在内存中!这取决于优化器做什么。

此检查发生在编译时

是的,它发生在编译时。

所以这让我认为s1实际上不存在于内存中,只有s2,因为s1实际上被移动到>s2.

不,这要看情况。它们两者、其中之一或都不存在于内存、缓存、寄存器中……要知道,您需要检查特定情况。

What does the documentation mean when it says "invalidates". Does this mean that Rust invalidates s1 and assigns the value that was in s1 to s2, so... s1 doesn't exist?

It means you, as developer, cannot access s1 anymore. So, from your point of view, you can think s1 doesn't exist.

Does it have any value?

No, because it doesn't exist (from your point of view).

does it really move it?

Depends on the program and the compiler. Conceptually, it does.

or is there still any value in s1 in memory?

Even without talking about moving, variables in general may never be in memory to begin with! It depends on what the optimizer does.

this check happens at compile time

Yes, it happens at compile time.

so it makes me think that s1 literally doesn't exist in memory and only s2, since s1 was literally moved to s2.

No, it depends. Both, one or none of them may exist in memory, caches, registers... To know you need to check the particular case.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文