我正在完成此练习(可变的逐个可变参考),但无法理解结果
#[derive(Debug)]
struct Person {
name: String,
age: u32,
}
fn birthday_mutable<'a>(mut person: &'a mut Person, replacement: &'a mut Person) {
println!("[InFn] Before : Alice {:p} : {:?}, Bob {:p} : {:?}", &person, person, &replacement, replacement);
person = replacement;
println!("[InFn] After : Alice {:p} : {:?}", &person, person);
}
fn main() {
let mut alice = Person {
name: String::from("Alice"),
age: 30,
};
let mut bob = Person {
name: String::from("Bob"),
age: 20,
};
println!("[Main] Before : Alice {:p} : {:?}, Bob {:p} : {:?}", &alice, alice, &bob, bob);
birthday_mutable(&mut alice, &mut bob);
println!("[Main] After : Alice {:p} : {:?}, Bob {:p} : {:?}", &alice, alice, &bob, bob);
}
在Birthday_mutable函数中,人员处于可变变量中。我们要做的第一件事是人=替换;。这将更改我们的人员变量所指向的内容,并且完全不会修改引用所指向的原始值。
尽管更改了人指向的内容,但结果是
[Main] Before : Alice 0x7ffd0c9b77e0 : Person { name: "Alice", age: 30 }, Bob 0x7ffd0c9b7820 : Person { name: "Bob", age: 20 }
[InFn] Before : Alice 0x7ffd0c9b7568 : Person { name: "Alice", age: 30 }, Bob 0x7ffd0c9b7570 : Person { name: "Bob", age: 20 }
[InFn] After : Alice 0x7ffd0c9b7568 : Person { name: "Bob", age: 20 }
[Main] After : Alice 0x7ffd0c9b77e0 : Person { name: "Alice", age: 30 }, Bob 0x7ffd0c9b7820 : Person { name: "Bob", age: 20 }
根据我的理解,结果不应该是这样吗?
[Main] Before : Alice 0x7ffd0c9b77e0 : Person { name: "Alice", age: 30 }, Bob 0x7ffd0c9b7820 : Person { name: "Bob", age: 20 }
[InFn] Before : Alice 0x7ffd0c9b7568 : Person { name: "Alice", age: 30 }, Bob 0x7ffd0c9b7570 : Person { name: "Bob", age: 20 }
[InFn] After : Alice 0x7ffd0c9b7568 : Person { name: "Bob", age: 20 }
[Main] After : Alice 0x7ffd0c9b77e0 : Person { name: "Bob", age: 20 } , Bob 0x7ffd0c9b7820 : Person { name: "Bob", age: 20 }
有人可以解释为什么吗?
输入时,堆栈状态的简化图为birthday_mutable
:
---- main ----
0x820 bob = Person { name: "Bob", age: 20 }
0x7e0 alice = Person { name: "Alice", age: 30 }
---- birthday_mutable ---
0x570 replacement = 0x820
0x568 person = 0x7e0
让我们命名以下突变A
和B
:
fn birthday_mutable<'a>(mut person: &'a mut Person, replacement: &'a mut Person) {
^^^A ^^^B
变异A
仅更新存储在address处的内容0x568
,因此仅影响引用birthday_mutable
的person
参数所保存的内容-因为参数是其函数的局部参数(即address0x568
在birthday_mutable
的堆栈帧中),所以此变异不会影响调用者。这是您在这里所做的:
person = replacement;
执行完上述语句后,地址处的内存0x568
包含该值0x820
(因此,birthday_mutable
'sperson
参数现在指的是bob
)-您可以通过检查&*person
而不是来查看此值&person
,即,person
所指的地址,而不是其person
自身所存储的地址。
突变B
只会更新存储在person
参数中所保存地址上的内容,也就是说,它会突变person
参数所引用的数据(即,alice
在main
堆栈框架中)。它是通过person
在分配过程中显式取消引用参数来实现的:
*person = Person { name: "Charlie".to_owned(), age: 10 };
与某些其他系统语言相比,Rust使他们更容易忘记这些细微差别,因为它会在函数调用和字段访问中自动执行反强制。不过,最好记住引擎盖下发生的事情。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句