1 个不稳定版本
使用旧的 Rust 2015
0.1.0 | 2017 年 6 月 14 日 |
---|
#75 in #helpers
124 每月下载次数
7KB
75 行
捕获一些常见的 collect
模式
Rust 中的一个常见模式是收集迭代器
let values = &["one","two","three"];
let v: Vec<_> = values.iter().cloned().collect();
let s: String = values.iter().cloned().collect();
println!("vector is {:?}, string is '{}'", v, s);
// vector is ["one", "two", "three"], string is 'onetwothree'
collect
非常灵活 - 但需要类型提示。这可以是一个不完整的类型,例如 Vec<_>
(让编译器填写空白)或者使用如下所示的涡轮鱼操作符 collect::Vec<_>()
。
尽管你习惯了这种方式,但我仍然觉得这个记法有点笨拙。ToVec 包是为了常见的案例而设计的
extern crate to_vec;
use to_vec::ToVec;
let v = values.iter().cloned().to_vec();
assert_eq!(v,&["one", "two", "three"]);
它是一个简单的特质(因此必须将其引入作用域),它为迭代器实现,就像 collect
一样依赖于 FromIterator
。
标准库中的一个奇妙的小特化将收集一个 Result<T,E>
迭代器,并返回一个 Result<Vec<T>,E>
,其中第一个遇到的错误将被返回。即使你了解这个隐藏的宝石,这种类型也很麻烦。因此有 to_vec_result
use to_vec::ToVecResult;
let numbers = "23E 5F5 FF00".split_whitespace()
.map(|s| u32::from_str_radix(s,16)).to_vec_result().unwrap();
assert_eq!(numbers,&[0x23E, 0x5F5, 0xFF00]);
尽管不太常用,但 collect
也会接受值的迭代器并从中创建一个 HashSet
。现在通常你只有一个引用迭代器,需要像 to_vec
示例中那样通过 cloned
。现在 to_set
被赋予一个引用迭代器,并隐式调用该迭代器上的 cloned
。这为我们提供了整洁的集合表示法
use to_vec::ToSet;
let colours = ["green","orange","blue"].iter().to_set();
let fruit = ["apple","banana","orange"].iter().to_set();
let common = colours.intersection(&fruit).to_set();
assert_eq!(common, ["orange"].iter().to_set());
同样,当收集映射时,你需要一个元组,而不是元组的引用。
const VALUES: &[(&str,i32)] = &[("hello",10),("dolly",20)];
let map = VALUES.iter().to_map();
assert_eq!(map.get("hello"),Some(&10));
assert_eq!(map.get("dolly"),Some(&20));
因此,to_set
和 to_map
隐式克隆。如果你确实有值,并且克隆可能很昂贵,你始终有旧的方法。