我有一个具有内部可变性的结构。
use std::cell::RefCell;
struct MutableInterior {
hide_me: 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 get_items(&self) -> &Vec<i32> {
&self.interior.borrow().vec
}
}
fn main() {
let f = Foo {
interior: RefCell::new(MutableInterior {
vec: Vec::new(),
hide_me: 2,
}),
};
let borrowed_f = &f;
let items = borrowed_f.get_items();
}
产生错误:
error[E0597]: borrowed value does not live long enough
--> src/main.rs:16:10
|
16 | &self.interior.borrow().vec
| ^^^^^^^^^^^^^^^^^^^^^^ temporary value 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 method body at 15:5...
--> src/main.rs:15:5
|
15 | / pub fn get_items(&self) -> &Vec<i32> {
16 | | &self.interior.borrow().vec
17 | | }
| |_____^
问题是我不能有一个Foo
返回借用的函数vec
,因为借用vec
只在 的生命周期内有效Ref
,但Ref
立即超出范围。
我认为Ref
必须坚持下去,因为:
RefCell<T>
使用 Rust 的生命周期来实现“动态借用”,这是一个可以声明对内部值的临时、独占、可变访问的过程。s 的借用RefCell<T>
是在“运行时”跟踪的,这与 Rust 的本地引用类型不同,后者在编译时完全静态跟踪。因为RefCell<T>
借用是动态的,所以可以尝试借用一个已经可变借用的值;当这种情况发生时,它会导致任务恐慌。
现在我可以写一个这样的函数来返回整个内部:
pub fn get_mutable_interior(&self) -> std::cell::Ref<MutableInterior>;
MutableInterior.hide_me
但是,这可能会将真正私有的实现细节的字段(在此示例中)暴露给Foo
.
理想情况下,我只想公开它vec
本身,可能有一个守卫来实现动态借用行为。然后来电者不必了解hide_me
。