rust - 在建模包含关系时了解生命周期管理

标签 rust lifetime containment

我正在努力思考 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 (什么都不返回)你可能打算使用 bob.car .要做到这一点......你会想要fmt::Debug为您的 Car 实现结构也是如此。这是适合您的有效修复程序。请注意所有 // <----- 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 - 在建模包含关系时了解生命周期管理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39113799/

相关文章:

Jquery 可拖动不适用于包含

string - 将字符串的首字母转换为大写的快速函数?

rust - Read::read_exact 不填充缓冲区

rust - 非引用类型是否总是满足“静态”的生命周期?

c++ - 子对象和包含对象之间的区别

c++ - 避免循环依赖——需要相互牵制

rust - 这个 "static"的生命周期是从哪里来的?

Rust Chrono 解析日期字符串、ParseError(NotEnough) 和 ParseError(TooShort)

types - 如何创建同时接受sqlx数据库池和事务的actix-web服务器?

rust - 为什么使用 "Self"作为参数类型会引发生命周期错误?