1
struct Parent<'a> {
    inner: Option<&'a mut Object>
}
impl<'a> Parent<'a> {
    fn new() -> Parent<'a> {
        Parent {
            inner: None,
        }
    }
    fn bind(&mut self, obj: &'a mut Object) {
        self.inner = Some(obj);
    }
    fn unbind(&mut self) {
        self.inner = None;
    }
}
struct Object {
    inner: u32,
}
fn main() {
    let mut obj = Object { inner: 0 };
    let mut parent1 = Parent::new();
    let mut parent2 = Parent::new();
    parent1.bind(&mut obj);
    parent1.unbind();
    // parent2.bind(&mut obj);
    // ^ error

}

構造Parent体フィールドには以下を格納する必要がありますOption:

struct Parent {
    inner: Option</*  magic  */>
}

fn main()を呼び出すまで、 でオブジェクトを操作する可能性を一時的にブロックする必要があります。.unbind()

4

2 に答える 2

2

借用チェッカーがコンパイル時にこれが正しいことを証明することは不可能です。ただしRefCell、実行時に動作することを確認するために使用でき、間違った場合はパニックになります。オブジェクトへの参照を Parent オブジェクトに格納する代わりに、オブジェクトRefMutを変更できる を格納できます。このbind関数は a への参照を受け取りRefCell、オブジェクトが既に借用されている場合はパニックになります。

use std::cell::*;

struct Parent<'a> {
    inner: Option<RefMut<'a, Object>>,
}
impl<'a> Parent<'a> {
    fn new() -> Parent<'a> {
        Parent {
            inner: None,
        }
    }
    fn bind(&mut self, obj: &'a RefCell<Object>) {
        self.inner = Some(obj.borrow_mut());
    }
    fn unbind(&mut self) {
        self.inner = None;
    }
}
struct Object {
    inner: u32,
}
fn main() {
    let obj = RefCell::new(Object { inner: 0 });
    let mut parent1 = Parent::new();
    parent1.bind(&obj);
    parent1.unbind(); // comment this line out and you get a runtime panic
    let mut parent2 = Parent::new();
    parent2.bind(&obj);
}
于 2015-11-06T08:55:51.823 に答える
0

の使用をスコープすることもできますparent1。にバインドするobjparent2、次のように使用できなくなりparent1ます。

let mut obj = Object { inner: 0 };
{
    let mut parent1 = Parent::new();
    parent1.bind(&mut obj);
    parent1.unbind();
}
let mut parent2 = Parent::new();
parent2.bind(&mut obj);
于 2015-11-06T10:21:42.820 に答える