尽可能采用`Iterator`代替`Vec`?

时间:2015-07-15 22:23:29

标签: arrays vector iterator rust

当一个函数将一系列值作为参数时,接受Iterator<T>而不是Vec<T>的方式是否合适?

通过这种方式,调用者可以自行决定如何存储系列(在Vec[T; N]或其他任何内容中,实际上Option<T>应该是可能的!)。此外,这消除了将所有内容转换为Vec的需要,并且在应用一些Iterator修饰符后,不需要.collect()!所以它也应该更快!

我错过了什么或这是应该做的方式吗?

1 个答案:

答案 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,因为它能够计算最终结果的预定时间,从而一次性分配正确长度的字符串。但它只是一个证明这个概念以及如何组合多种奇特的技术。)