创建一个新对象并不等于“移出值”——我哪里错了?

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

以下 Rust 代码来自《Programming Rust》一书。我插入了一些(希望是正确的?)要打印的指针地址,以便检查对象驻留在内存中的位置。

struct Person {name: Option<String>, birth: i32}
let mut composers = Vec::new();
composers.push(Person {name: Some("Palestrina".to_string()), birth: 1525});
println!("first_elem addr {:p}", &composers[0].name);
let first_name = std::mem::replace(&mut composers[0].name, None);
println!("first_elem addr {:p}", &composers[0].name);
println!("first name addr {:p}", &first_name);

请注意,最后显示的对象地址与值 Some("Palestrina".to_string()) 所在的原始位置完全不同。 鉴于这是事实:我认为可以公平地说创建了一个新对象(其值等于作曲家[0]的前名称,但它仍然位于新的内存位置)。 然而,书中使用的术语声称有所不同:“该值已

移出

作曲家[0].name”。现在,我一直以为一动就是不行!创建一个新对象,但只是原始值的新所有者(在同一内存位置!)。然而,这种情况并非如此。 所以我的问题是:我的地址显示是否有错误,或者“移动”的概念是否有不同的定义?

rust move
1个回答
0
投票

在这种情况下,

first_name

是函数堆栈帧上的一个对象,并且与

composers[0].name
不同(具有不同的地址)。

std::mem::replace(&mut composers[0].name, None)

获取之前在

composers[0].name
中的内容,并通过将其放入
first_name
中的堆栈来返回它。因此,它具有与
composers[0].name
不同的地址是完全自然的。
 Rust 术语中的“移动”是一个抽象概念,指的是移动对象的“所有权”。它不一定对内存使用或地址进行物理上的一对一转换。

© www.soinside.com 2019 - 2024. All rights reserved.