You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rust结构体移动语义疑问:为何移动后变量内存地址不同?

Rust移动语义:含Copy类型字段结构体的常见疑问

先看示例代码:

struct Book {
    author: &'static str,
    title: &'static str,
    year: u32,
}

fn main() {
    let bookA = Book {
        author: "Douglas Hofstadter",
        title: "Gödel, Escher, Bach",
        year: 1979,
    };
    
    let addr_bookA: *const Book = &bookA;
    let bookB = bookA; // Move occurs here
    
    // Getting the memory addresses as raw pointers
    
    let addr_bookB: *const Book = &bookB;
    
    println!("Address of bookA: {:p}", addr_bookA);
    println!("Address of bookB: {:p}", addr_bookB);
}

运行输出:

Address of bookA: 0x7fff20b1a0b0
Address of bookB: 0x7fff20b1a0e0

针对疑问逐一解答:

1. 为何结构体移动后,原变量与目标变量的内存地址仍不相同?

bookA和bookB是两个独立的栈上变量,它们在栈上的存储位置从声明时就是分开的。所谓“移动”操作,是把bookA结构体里的所有字段值复制到bookB的内存空间中,而非让两个变量共享同一块内存。两个变量各自占据栈上的不同位置,所以打印出的地址自然不一样。

2. 此场景下是否实际发生了拷贝?若有,为何Rust将其视为移动操作?

这里确实发生了浅拷贝:结构体里的两个字符串指针(&'static str)和一个u32整数,都被复制到了bookB的内存里。但Rust把这个操作叫做“移动”,核心原因是Book结构体没有实现Copy trait。

Rust的规则是:只要类型没实现Copy,赋值操作就会触发移动语义——移动完成后,原变量bookA会被标记为“无效”,后续代码中不能再使用它;而如果类型实现了Copy,赋值后原变量依然可以正常使用。这里的浅拷贝是移动操作的底层行为,但Rust用“移动”这个概念来强调原变量的状态变化,而非单纯描述底层的复制动作。

内容的提问来源于stack exchange,提问作者dowjones123

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 18:52:59