当一个函数将一系列值作为参数时,接受Iterator<T>
而不是Vec<T>
的方式是否合适?
通过这种方式,调用者可以自行决定如何存储系列(在Vec
,[T; N]
或其他任何内容中,实际上Option<T>
应该是可能的!)。此外,这消除了将所有内容转换为Vec
的需要,并且在应用一些Iterator修饰符后,不需要.collect()
!所以它也应该更快!
我错过了什么或这是应该做的方式吗?
答案 0 :(得分:11)
您描述的这种功能通常应该通常采用IntoIterator<Item = T>
;因此它可以接受Iterator<T>
和Vec<T>
作为输入。
这也可以与其他技术结合使用;例如,此方法concat
将接受&[&str]
(因此&Vec<&str>
通过自动deref / ref强制),&[String]
(以及&Vec<String>
),a &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
,因为它能够计算最终结果的预定时间,从而一次性分配正确长度的字符串。但它只是一个证明这个概念以及如何组合多种奇特的技术。)