Rust中filter闭包的双重引用(&&)类型疑问及后续问题
Rust迭代器filter闭包的类型疑问解答
先明确代码上下文:
use std::collections::HashMap; #[derive(PartialEq, Debug)] enum Progress { Complete, None, } fn count_iterator(map: &HashMap<String, Progress>, value: Progress) -> usize { // 注释中正确写法:map.values().filter(|x| **x == value).count() map.values().filter(|x| x == &value).count() }
问题1:为什么filter闭包中的x是&&Progress类型?
没错,HashMap::values()返回的迭代器确实产生&Progress类型的元素,但Iterator::filter方法的设计是传递迭代器元素的引用给闭包,而非直接传递元素本身。这是因为filter只需要检查元素是否符合条件,不需要获取元素所有权,所以会对迭代器的元素再套一层引用:
- 迭代器输出类型:
&Progress - filter闭包接收的参数类型:
&&Progress
问题2:既然x是&&Progress,为什么*x是&Progress类型?(注:你问题中的&x应为笔误,&x实际是&&&Progress类型)
这是单次解引用的结果:
- x的类型是
&&Progress,对x做一次解引用(*x),会去掉最外层的引用,得到&Progress类型。 - 如果做双重解引用(
**x),会直接得到Progress类型,这也是注释里**x == value能正确编译的原因——此时两边都是Progress类型,可以直接比较。
问题3:闭包(|&x: &Progress| x == &value)中,x为什么是&Progress类型?
这是Rust的模式匹配在起作用:闭包参数&x是一个引用模式,它会解构传入的&&Progress类型参数:
- 传入的参数是
&&p(其中p是Progress实例) - 模式
&x会匹配外层的&,把内层的&p绑定到变量x上 - 因此x的类型就是
&Progress
内容的提问来源于stack exchange,提问作者jcleow
相关产品推荐
相关产品推荐

