如何创建仅包含过滤后元素的新HashMap?(Rust)
Rust HashMap过滤生成新HashMap的正确实现
你尝试的代码编译失败的核心原因是:HashMap的into_iter()迭代器产出的是(键, 值)形式的元组,而非两个独立参数,filter闭包需要接收单个元组参数,而非分开的k和v。
你的错误代码:
let map = HashMap::new(); map.insert(1, "foo"); map.insert(2, "bar"); let map2 = map.into_iter().filter(|k, v| k > 1).collect(); // doesn't compile
对应的编译错误:
error[E0593]: closure is expected to take 1 argument, but it takes 2 arguments --> | | let map2 = map.into_iter().filter(|k, v| k > 1).collect(); // doesn't compile | ^^^^^^ ------ takes 2 arguments | | | expected closure that takes 1 argument
正确实现方式
以下两种写法都可以生成符合要求的新HashMap:
方式一:闭包参数解构元组
直接在闭包参数里解构元组,同时处理引用类型的比较:
use std::collections::HashMap; fn main() { let mut map = HashMap::new(); map.insert(1, "foo"); map.insert(2, "bar"); // 显式指定目标类型为HashMap,collect需要明确类型 let map2: HashMap<_, _> = map.into_iter() .filter(|(k, _v)| *k > 1) // 解引用k,直接和1比较 .collect(); println!("{:?}", map2); // 输出: {2: "bar"} }
方式二:闭包内匹配元组
如果觉得解构不够直观,也可以用显式的变量绑定处理元组:
use std::collections::HashMap; fn main() { let mut map = HashMap::new(); map.insert(1, "foo"); map.insert(2, "bar"); let map2: HashMap<_, _> = map.into_iter() .filter(|item| { let (k, _) = item; *k > 1 }) .collect(); println!("{:?}", map2); // 输出: {2: "bar"} }
关键注意点
collect()是泛型方法,必须显式指定map2的类型为HashMap<_, _>(下划线让编译器自动推导键值类型),否则编译器无法确定要收集成什么类型。filter闭包接收的是迭代元素的引用,所以元组里的k是&i32类型,需要通过解引用*k或者和&1比较来完成数值判断。
内容的提问来源于stack exchange,提问作者yegor256
相关产品推荐
相关产品推荐

