理解 Rust 移动语义:所有权转移是否涉及数据复制?

问题描述 投票:0回答:1

作为 Rust 的初学者,我突然对 Rust 中的

move
语义以及所有权转移时数据是否被复制感到好奇。

#[derive(Debug)]
struct Foo {
    name: i32,
    age: i32,
}

fn main() {
    let foo = Foo { name: 111, age: 1 };

    let ptr_foo = std::ptr::addr_of!(foo);
    println!("Address of foo: {:p}", ptr_foo);

    let bar = foo;

    let ptr_bar = std::ptr::addr_of!(bar);
    println!("Address of bar: {:p}", ptr_bar);
}

我最初以为“有一个变量 foo,移动后,我们简单地将其重命名为 bar”,从而避免了复制其对应数据的需要。

为了进一步调查,我使用了 VSCode 中的调试功能以及名为“Hex Editor”的插件,发现

foo
bar
(内存地址
0x7fffffffd7d8
0x7fffffffd828
)包含相同的数据 (
6F 00 00 00 01 00 00 00
) ).

enter image description here

这是否表明 Rust 即使在

move
期间实际上也会执行复制操作,例如在本例中复制结构?此行为是否会根据是否处于发布模式而有所不同?

rust move
1个回答
0
投票

“移动”在许多语言(不仅仅是 Rust)中是一个语义术语,指的是“所有权转移”,并且并不“必然”规定该转移的机制。 在 Rust 中,移动值会将数据复制到其他位置,但会使值的源不可用(除非该源稍后使用有效值重新初始化)。 这是如何实现的,Rust 是从源到目标的按位复制。 在更高的优化级别上,可以忽略此副本,但也可能不会。 特别是,获取 foo

bar 的地址可能会阻止优化器实际删除副本,因为它无法统一它们的内存位置。

换句话说:

如果您试图查看代码将如何编译,

不要更改该代码以检查代码内部的值

,否则您几乎肯定会以某种方式更改优化器的行为。 相反,请查看生成的机器代码。

最新问题
© www.soinside.com 2019 - 2024. All rights reserved.