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 隐式克隆。如果你确实有值,并且克隆可能很昂贵,你始终有旧的方法。