我有一个具有内部可变性的结构。
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的生命周期来实现“动态借用”,这一过程使人们可以要求对内部价值进行临时,排他,可变的访问。RefCell<T>s的借记是在“运行时”进行跟踪的,这与Rust的本机引用类型不同,后者在编译时是完全静态跟踪的。由于RefCell<T>借贷是动态的,因此可以尝试借入已经可变借贷的值;当这种情况发生时,将导致任务恐慌。
现在,我可以改写这样的函数来返回整个内部:
pub fn get_mutable_interior(&self) -> std::cell::Ref<MutableInterior>;
但是,这可能会将字段(MutableInterior.hide_me在此示例中)暴露为真正的私有实现细节Foo。
理想情况下,我只想公开vec自身,可能需要配备警卫来实现动态借用行为。然后,呼叫者不必了解hide_me。
有只小跳蛙
函数式编程
侃侃尔雅