【问题标题】:Deduping a list of lists runs afoul of the Borrow Checker对列表列表进行重复数据处理与借用检查器发生冲突
【发布时间】:2021-04-18 00:42:28
【问题描述】:

我正在尝试对列表列表进行重复数据删除。我已经有一个程序可以毫无问题地对单个列表进行重复数据删除。但是,现在我想同时连接多个列表并进行重复数据删除,而借用检查器可以使用它的旧技巧。

在下面的代码中,关于 FeelValue 唯一需要了解的是它是 Clone 而不是 Copy。关键目标是仅通过一次 Clone 调用即可完成连接和重复数据删除。最终结果是返回deduped Vec,它必须具有稳定的排序。通过两个克隆调用很容易做到这一点:只需将 set.insert(&item) 更改为 set.insert(item.clone()) 并更改 HashSet 的类型。

如果需要的话,我很乐意在 RefCells 内排空或弄乱 Vec

let mut list_vecs: Vec< Rc<RefCell<Vec<FeelValue>>> > = Vec::new();

// Do something to fill up list_vecs...
// .....SNIP.....

let mut deduped: Vec<FeelValue> = Vec::new();
let mut set: HashSet<&FeelValue> = HashSet::new();
for rr_vec in list_vecs.iter() {
  let rr_vec_b = rr_vec.borrow();
  for item in rr_vec_b.iter() {
    if set.insert(&item) {
      deduped.push(item.clone());
    }
  }          
}

错误是:

`rr_vec_b` does not live long enough

borrowed value does not live long enoughrustc(E0597)

这是一个类似的例程,它成功地对单个列表进行重复数据删除。 下面列表的定义为:list: &amp;Vec&lt;FeelValue&gt;

|list| { 
  let mut set: HashSet<&FeelValue> = HashSet::with_capacity(list.len());
  let deduped: Vec<FeelValue> = list
    .iter()
    .filter(|item| set.insert(item))
    .cloned()
    .collect();
  FeelValue::new_list(deduped) 
}

我只是想不出一种将列表列表链接到单个迭代器中的方法,或者我可以使用相同的方法。

【问题讨论】:

    标签: rust duplicates borrow-checker


    【解决方案1】:

    您的问题不在于借用检查器本身,而在于RefCell。从borrow() 返回的Ref 必须在从它派生的任何引用的持续时间内保持在范围内。

    一个技巧是将所有RefCells 中的Refs 收集到一个Vec 中,以便在迭代引用时都保持在范围内:

    let list_vecs: Vec<Rc<RefCell<Vec<FeelValue>>>> = Vec::new();
    let list_vec_refs: Vec<Ref<Vec<FeelValue>>> = list_vecs.iter().map(|v| v.borrow()).collect();
    
    let mut deduped: Vec<FeelValue> = Vec::new();
    let mut set: HashSet<&FeelValue> = HashSet::new();
    for rr_vec in list_vec_refs.iter() {
        for item in rr_vec.iter() {
            if set.insert(&item) {
                deduped.push(item.clone());
            }
        } 
    }
    

    playground 上查看它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-01
      • 1970-01-01
      • 2010-11-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多