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
相关产品推荐
相关产品推荐

