Here是示例代码:

use std::collections::BTreeMap;

fn main() {
    let mut map: BTreeMap<u8, Vec<u8>> = BTreeMap::new();
    let idx = map.iter_mut().find(|t| {
        let (&k, &mut v) = t;
        v.is_empty()
    });
    idx.map(|t| {
        let (&k, &mut v) = t;
        v.push(5);
    });
}

错误:
<anon>:6:13: 6:25 error: mismatched types:
 expected `&(&u8, &mut collections::vec::Vec<u8>)`,
    found `(_, _)`
(expected &-ptr,
    found tuple) [E0308]
<anon>:6         let (&k, &mut v) = t;
                     ^~~~~~~~~~~~

元组的类型为&(&u8, &mut collections::vec::Vec<u8>),因此我希望它可以与以下内容一起解压缩:
let (&k, &mut v) = *t;


<anon>:10:28: 10:30 error: type `(&u8, &mut collections::vec::Vec<u8>)` cannot be dereferenced
<anon>:10         let (&k, &mut v) = *t;
                                     ^~

如何打开包装并将其用于可变目的?

最佳答案

查看错误消息:

 expected `&(&u8, &mut collections::vec::Vec<u8>)`,
    found `(_, _)`
(expected &-ptr,
    found tuple) [E0308]

编译器希望与引用进行匹配,但是代码没有提供这种引用。将绑定(bind)更改为let &(&k, &mut v) = t。然后,您会收到许多其他错误:
  • 使用&mut foo进行匹配意味着foo将去除&mut,然后将结果值移到foo。这是因为它是一个模式匹配,就像let Some(foo) = ...如何“剥离” Some一样。
  • 您不能移动Vec,因为它是BTreeMap所拥有的,因此您需要对其进行引用。这是通过ref关键字而不是&运算符完成的。
  • 通常,您还可以直接在闭包参数中(而不是在第二个变量中)进行模式匹配。
  • 因为map将项目的所有权转移到了闭包中,所以您可以给mut绑定(bind),而无需任何引用。
  • 由于未使用k,因此用下划线(_)替换名称是很常见的。

  • let idx = map.iter_mut().find(|&(k, ref v)| {
        v.is_empty()
    });
    
    idx.map(|(_, mut v)| {
        v.push(5);
    });
    



    如果您的意思是“我怎样才能将闭包中的值突变为find”,答案是“您不能”。 Find返回对迭代项(&Self::Item)的不变引用:
    fn find<P>(&mut self, predicate: P) -> Option<Self::Item>
        where P: FnMut(&Self::Item) -> bool
    

    即使您的Self::Item可能是可变引用,对可变引用的不可变引用仍然是不可变的。

    关于dictionary - 如何从Rust中的迭代器解包BTreeMap项目元组?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/37658848/

    10-11 17:58