rust - 将 Vec<Rc<RefCell<T>>> 转换为 &[&mut T]

标签 rust lifetime

我有一个引用计数向量 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/

相关文章:

hash - 如何使用氧化钠 crate 对字符串进行哈希处理?

rust - 检查 Option 是否包含特定 Some 值的最佳方法?

rust - 如何将枚举值与整数匹配?

rust - 借用检查器提示多次借用,而只有一次会发生

rust - 返回对具有泛型 Fn 特征/值的泛型类型的引用

reference - 如何为对结构的引用实现 Add 特性?

rust - 为什么在使用特征时参数类型必须是 'static

rust - 如何解决 "indicate anonymous lifetime <' _>”错误?

c# - 长期使用Entities时在C#中使用EntityFramework

rust - 如何使用可变成员 Vec?