在建模包含关系时了解生命周期管理
Understanding lifetime management while modeling containment relationship
我正在努力思考 Rust 对象的生命周期。当我执行关系建模练习时,我 运行 遇到以下错误。
error: cannot borrow `bob` as mutable because `bob.gender` is also borrowed as immutable [E0502]
代码在这里:
// Business Case:
// Design a person type. A person may own a Car. A person should be able to buy and sell cars.
// Two persons should be able to exchange (or trade) their cars.
//
// Purpose of exercise:
// Understand lifetime management in Rust while modeling containment relationship.
// (meaning: when an object contains a reference to another object.)
struct Car {
make: &'static str,
model: &'static str,
year: &'static str,
}
struct Person<'a> {
name: &'static str,
gender: &'static str,
car: Option<&'a Car>,
}
impl<'a> Person<'a> {
fn new(name: &'static str, gender: &'static str, car: Option<&'a Car>) -> Person<'a> {
Person {
name: name,
gender: gender,
car: None,
}
}
fn buy_car(&mut self, c: &'a Car) {
self.car = Some(c);
}
fn sell_car(&mut self) {
self.car = None;
}
}
fn main() {
let pickup = Car {
make: "Ford",
model: "F250",
year: "2006",
};
let mut bob = Person::new("Bob", "Male", None);
println!("A {:?} whose name is {:?} has just purchased a 2006 {:?}.",
bob.gender,
bob.name,
bob.buy_car(&pickup));
}
任何人都可以插话我到底错过了什么吗?我不确定引用计数或 Box 是否可行,需要更多见解。
您的问题归结为您使用 buy_car
(returns 什么都没有),而您可能打算使用 bob.car
。为此……您还需要为 Car
结构实现 fmt::Debug
。这是适合您的有效修复程序。请注意我添加的所有 // <----- parts
(here it is on the Playground):
#[derive(Debug)] // <------------ Have the compiler implement fmt::Debug for you
struct Car {
make: &'static str,
model: &'static str,
year: &'static str,
}
struct Person<'a> {
name: &'static str,
gender: &'static str,
car: Option<&'a Car>,
}
impl<'a> Person<'a> {
fn new(name: &'static str, gender: &'static str, car: Option<&'a Car>) -> Person<'a> {
Person {
name: name,
gender: gender,
car: None,
}
}
fn buy_car(&mut self, c: &'a Car) {
self.car = Some(c);
}
fn sell_car(&mut self) {
self.car = None;
}
}
fn main() {
let pickup = Car {
make: "Ford",
model: "F250",
year: "2006",
};
let mut bob = Person::new("Bob", "Male", None);
bob.buy_car(&pickup); // <------- Buy the car separately
println!("A {:?} whose name is {:?} has just purchased a 2006 {:?}.",
bob.gender,
bob.name,
bob.car); // <------------ Pass the car into the debug string
}
顺便说一句 - 我会考虑在适当的地方使用 String
来减少传递引用和生命周期的需要。在您的小示例中可能不那么重要,但随着代码变大,它们会变得棘手。
我正在努力思考 Rust 对象的生命周期。当我执行关系建模练习时,我 运行 遇到以下错误。
error: cannot borrow `bob` as mutable because `bob.gender` is also borrowed as immutable [E0502]
代码在这里:
// Business Case:
// Design a person type. A person may own a Car. A person should be able to buy and sell cars.
// Two persons should be able to exchange (or trade) their cars.
//
// Purpose of exercise:
// Understand lifetime management in Rust while modeling containment relationship.
// (meaning: when an object contains a reference to another object.)
struct Car {
make: &'static str,
model: &'static str,
year: &'static str,
}
struct Person<'a> {
name: &'static str,
gender: &'static str,
car: Option<&'a Car>,
}
impl<'a> Person<'a> {
fn new(name: &'static str, gender: &'static str, car: Option<&'a Car>) -> Person<'a> {
Person {
name: name,
gender: gender,
car: None,
}
}
fn buy_car(&mut self, c: &'a Car) {
self.car = Some(c);
}
fn sell_car(&mut self) {
self.car = None;
}
}
fn main() {
let pickup = Car {
make: "Ford",
model: "F250",
year: "2006",
};
let mut bob = Person::new("Bob", "Male", None);
println!("A {:?} whose name is {:?} has just purchased a 2006 {:?}.",
bob.gender,
bob.name,
bob.buy_car(&pickup));
}
任何人都可以插话我到底错过了什么吗?我不确定引用计数或 Box 是否可行,需要更多见解。
您的问题归结为您使用 buy_car
(returns 什么都没有),而您可能打算使用 bob.car
。为此……您还需要为 Car
结构实现 fmt::Debug
。这是适合您的有效修复程序。请注意我添加的所有 // <----- parts
(here it is on the Playground):
#[derive(Debug)] // <------------ Have the compiler implement fmt::Debug for you
struct Car {
make: &'static str,
model: &'static str,
year: &'static str,
}
struct Person<'a> {
name: &'static str,
gender: &'static str,
car: Option<&'a Car>,
}
impl<'a> Person<'a> {
fn new(name: &'static str, gender: &'static str, car: Option<&'a Car>) -> Person<'a> {
Person {
name: name,
gender: gender,
car: None,
}
}
fn buy_car(&mut self, c: &'a Car) {
self.car = Some(c);
}
fn sell_car(&mut self) {
self.car = None;
}
}
fn main() {
let pickup = Car {
make: "Ford",
model: "F250",
year: "2006",
};
let mut bob = Person::new("Bob", "Male", None);
bob.buy_car(&pickup); // <------- Buy the car separately
println!("A {:?} whose name is {:?} has just purchased a 2006 {:?}.",
bob.gender,
bob.name,
bob.car); // <------------ Pass the car into the debug string
}
顺便说一句 - 我会考虑在适当的地方使用 String
来减少传递引用和生命周期的需要。在您的小示例中可能不那么重要,但随着代码变大,它们会变得棘手。