如何告诉Rust编译器借用已经结束?

时间:2016-06-17 13:11:40

标签: rust borrow-checker

关于Rust的checking out tutorials,我遇到了借阅检查器的问题。以下代码无法编译:

struct Car {
    model: String,
}

struct Person<'a> {
    car: Option<&'a Car>,
}

impl<'a> Person<'a> {
    fn new() -> Person<'a> {
        Person { car: None }
    }

    fn buy_car(&mut self, c: &'a Car) {
        // how to say that Person don't borrow the old car any longer?
        self.car = Some(c);
    }
}

fn main() {
    let civic = Car { model: "Honda Civic".to_string() };
    let mut ghibli = Car { model: "Maserati Ghibli".to_string() };
    let mut bob = Person::new();

    bob.buy_car(&ghibli);

    bob.buy_car(&civic);

    // error: cannot borrow `ghibli` as mutable because it is also borrowed as immutable
    let anything = &mut ghibli;
}

据我所知,由于它的词汇性质,Rust的借阅检查器无法识别ghibli的借用已经结束。

但我真的很想知道如何解决Rust这个问题呢?我是否必须以某种方式使用Rc<T>Box<T>

2 个答案:

答案 0 :(得分:2)

&#34; Rust方式&#34;告诉借用检查员,借款结束是为了引入一个新的范围:

fn main() {
    let civic = Car{model: "Honda Civic".to_string()};
    let mut ghibli = Car{model: "Maserati Ghibli".to_string()};
    {
        let mut bob = Person::new();

        bob.buy_car(&ghibli);

        bob.buy_car(&civic);
    }
    let anything = &mut ghibli;
}

你必须意识到的是,在你的例子中,(并且可能在大多数情况下,无论如何)借用检查器是正确的。

Bob借用ghibli的引用。它仍存在于car字段的主要方法的末尾。

答案 1 :(得分:2)

这种情况下静态借用规则不起作用,因为正在进行的动态行为无法告诉编译器。

您需要使用Rc<T>,它可以在运行时进行借用检查;或者如果您需要可变访问权限Rc<Cell<T>>Rc<RefCell<T>>。然后只要你以动态安全的方式访问它,一切都会很好。