我有一個內部可變性的結構。如何在不破壞封裝的情況下返回對RefCell內的某些內容的引用?
use std::cell::RefCell;
struct MutableInterior {
hideMe: i32,
vec: Vec<i32>,
}
struct Foo {
//although not used in this particular snippet,
//the motivating problem uses interior mutability
//via RefCell.
interior: RefCell<MutableInterior>,
}
impl Foo {
pub fn getItems(&self) -> &Vec<i32> {
&self.interior.borrow().vec
}
}
fn main() {
let f = Foo {
interior: RefCell::new(MutableInterior {
vec: Vec::new(),
hideMe: 2,
}),
};
let borrowed_f = &f;
let items = borrowed_f.getItems();
}
產生錯誤:
error: borrowed value does not live long enough
--> src/main.rs:16:10
|
16 | &self.interior.borrow().vec
| ^^^^^^^^^^^^^^^^^^^^^^ does not live long enough
17 | }
| - temporary value only lives until here
|
note: borrowed value must be valid for the anonymous lifetime #1 defined on the body at 15:40...
--> src/main.rs:15:41
|
15 | pub fn getItems(&self) -> &Vec<i32> {
| _________________________________________^ starting here...
16 | | &self.interior.borrow().vec
17 | | }
| |_____^ ...ending here
的問題是,我不能有一個功能上Foo
返回借來vec
,因爲借來的vec
是僅適用於Ref
的壽命,但Ref
立即超出範圍。
我覺得Ref
必須堅持圍繞because:
RefCell uses Rust's lifetimes to implement 'dynamic borrowing', a process whereby one can claim temporary, exclusive, mutable access to the inner value. Borrows for RefCells are tracked 'at runtime', unlike Rust's native reference types which are entirely tracked statically, at compile time. Because RefCell borrows are dynamic it is possible to attempt to borrow a value that is already mutably borrowed; when this happens it results in task panic.
現在我可以改爲寫這樣一個函數,返回整個內飾:
pub fn getMutableInterior(&self) -> std::cell::Ref<MutableInterior>;
然而,這可能暴露出場(MutableInterior.hideMe
在這個例子)是真正的私人執行細節到Foo
。
理想情況下,我只是想公開vec
本身,可能帶有警衛以實現動態借用行爲。然後來電者不必知道hideMe
。
這是做到這一點的唯一/慣用的方法是什麼?似乎有點麻煩......雖然我認爲,而不是一個getItems()方法,你可以直接借用內部塊在那裏它會超出範圍(或...) – norcalli 2015-04-02 08:37:08
@Norcalli在具體如果是'RefCell'的情況,當引用超出作用域時(這是'Ref'的析構函數的作用),該對象需要被通知。在這裏,我們需要保持這種行爲(OP的錯誤是由於'Ref'實例被放棄得太早),因此封裝了它。 – Levans 2015-04-02 08:40:43