我有一个具有内部可变性的结构体。
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>
的借用是在运行时跟踪的,而 Rust 的本机引用类型完全是在编译时静态跟踪的。由于RefCell<T>
借用是动态的,因此可能会尝试借用已经被可变借用的值;当发生这种情况时,它会导致任务恐慌。
pub fn get_mutable_interior(&self) -> std::cell::Ref<MutableInterior>;
然而,这可能会将实际上是私有实现细节的字段(例如此示例中的
MutableInterior.hide_me
)暴露给Foo
。理想情况下,我只想公开vec
本身,可能带有一个保护来实现动态借用行为。然后调用者就不必了解hide_me
。
UnsafeCell
的实现,因为它很可能会引入内存不安全性。 - ShepmasterMutex
没有map
,这意味着这种情况只能单线程(从cell.rs
和mutex.rs
中的代码来看,我认为至少需要重新设计MutexGuard
以支持此类操作)。我认为在这种情况下可以使用 @Levan 下面的一种变体解决方案,但我还没有尝试过。 - Kevin Anderson