【问题标题】:Take an `Iterator` instead of `Vec` when possible?尽可能使用“Iterator”而不是“Vec”?
【发布时间】:2015-07-15 22:23:28
【问题描述】:
当函数将一系列值作为参数时,接受Iterator<T> 而不是Vec<T> 是否被认为是好的风格?
这样,调用者可以自行决定如何存储系列(在Vec、[T; N] 或其他任何东西中,实际上应该可以使用Option<T>!)。此外,这消除了将您拥有的任何内容转换为 Vec 的需要,并且在应用了一些迭代器修饰符之后,不需要 .collect()!所以它也应该更快!
我错过了什么还是应该这样做?
【问题讨论】:
标签:
arrays
vector
iterator
rust
【解决方案1】:
您描述的此类函数通常通常应采用IntoIterator<Item = T>;因此它可以接受Iterator<T> 和Vec<T> 作为输入。
这也可以与其他技术结合使用;例如,此方法 concat 将接受 &[&str](因此 &Vec<&str> 通过自动 deref/ref 强制)、&[String](因此 &Vec<String>)、&str 迭代器、String 迭代器, 等等:
use std::borrow::Borrow;
fn concat<T: Borrow<str>, Iter: IntoIterator<Item = T>>(iter: Iter) -> String {
iter.into_iter() // -> impl Iterator<Item = T>
.map(|s| s.borrow()) // -> impl Iterator<Item = &str>
.collect() // -> String
}
(这个具体的例子实际上通常更适合SliceConcatExt,因为它能够计算出最终结果会提前多长时间,从而一次分配正确长度的字符串。但这只是一个证明概念以及如何组合多种花哨的技术。)