我有一个引用计数向量 RefCell
s 并想传递一个 Vec
( mut
) 对 RefCell
的引用s 变成一个函数。引用的生命周期不应超过函数调用。
这似乎应该是可能的(只有一个,像 &*x.borrow_mut()
是可以的)。我试图保留 RefMut
的中间向量和 &mut
来控制生命周期,但我还没有找到让它工作的方法:
use std::cell::{RefCell,RefMut};
use std::vec::Vec;
use std::rc::Rc;
trait SomeTrait {}
struct Wrapper<'a> {
pub r: &'a mut SomeTrait,
}
fn foo(_: &[Wrapper]) {}
fn main() {
let mut v1: Vec<Rc<RefCell<SomeTrait>>> = unimplemented!();
let mut v_rm: Vec<RefMut<_>> = v1.iter_mut().map(|r| r.borrow_mut()).collect();
let mut v_wrapper: Vec<Wrapper> = v_rm.iter_mut().map(|ref mut rm| Wrapper{ r: &mut ***rm }).collect();
foo(&v_wrapper[..]);
}
( playground )
这显然是一个终身问题:
rustc 1.11.0 (9b21dcd6a 2016-08-15)
error: borrowed value does not live long enough
--> <anon>:17:60
|>
17 |> let mut v_wrapper: Vec<Wrapper> = v_rm.iter_mut().map(|ref mut rm| Wrapper{ r: &mut ***rm }).collect();
|> ^^^^^^^^^^
note: reference must be valid for the block suffix following statement 2 at 17:107...
--> <anon>:17:108
|>
17 |> let mut v_wrapper: Vec<Wrapper> = v_rm.iter_mut().map(|ref mut rm| Wrapper{ r: &mut ***rm }).collect();
|> ^
note: ...but borrowed value is only valid for the block at 17:71
--> <anon>:17:72
|>
17 |> let mut v_wrapper: Vec<Wrapper> = v_rm.iter_mut().map(|ref mut rm| Wrapper{ r: &mut ***rm }).collect();
|> ^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to previous error
我控制foo
所以可以改变它的 API 使事情变得更容易,但它在不同的模块/ crate 中,我真的不希望它需要知道我保留我的 SomeTrait
Rc<RefCell<_>>
中的对象.
最佳答案
当然可以编写以 Vec<RefMut<T>>
开头的代码并创建一个 Vec<&mut T>
从那个( generic example ),我建议你改变 foo
的签名.许多算法不需要切片提供的随机访问,如果函数可以接受迭代器而不是切片,则您不需要创建两个 整个附加 Vec
s,除了调用函数变得更简单。我在想这样的签名
fn foo<I, R>(widgets: I)
where I: IntoIterator<Item=R>,
R: DerefMut<Target=SomeTrait>
{
for widget in widgets {
// ...
}
}
然后您所需要的就是生成一个迭代器,该迭代器会产生 RefMut
的,这很容易用 v1.iter_mut().map(|x| x.borrow_mut())
完成. Here's一个例子。
关于rust - 将 Vec<Rc<RefCell<T>>> 转换为 &[&mut T],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39701253/