gpt4 book ai didi

rust - Rust中的可变按引用传递

转载 作者:行者123 更新时间:2023-12-03 11:41:00 26 4
gpt4 key购买 nike

我正在完成此练习(可变的逐个可变引用),但无法理解结果
https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=42ff75b2464a99337b7738fba3597512

#[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

让我们将以下突变命名为 AB:
fn birthday_mutable<'a>(mut person: &'a mut Person, replacement: &'a mut Person) {
^^^A ^^^B
  • 突变A仅更新存储在地址0x568上的内容,因此仅影响引用birthday_mutableperson参数的内容-由于参数是函数的局部参数(即,地址0x568birthday_mutable的堆栈框架中),因此此突变不会影响调用者。这是您在这里所做的:
    person = replacement;
    执行完以上语句后,地址0x568的内存包含值0x820(因此birthday_mutableperson参数现在称为bob)–您可以通过检查&*person而不是&person来查看此内容,即person所引用的对象的地址,而不是person本身存储的地址。
  • 突变B仅更新存储在地址0x7e0本身的任何地址(0x568)上存储的内容,也就是说,它会突变person参数引用的数据(即alice堆栈框架中的main)。它是通过在变异时取消引用person参数来实现的:
    *person = Person { name: "Charlie".to_owned(), age: 10 };
    与其他系统语言相比,Rust使它更容易忽略取消引用,因为它具有automatically performs deref coercion in function calls和字段访问权限。不过,最好记住引擎盖下发生的事情。
  • 关于rust - Rust中的可变按引用传递,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65964852/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com