尽可能使用“Iterator”代替“Vec”?

问题描述 投票:0回答:1

当函数采用一系列值作为参数时,接受

Iterator<T>
而不是
Vec<T>
是否被视为良好的风格?

这样,调用者可以自己决定如何存储该系列(在

Vec
[T; N]
或其他任何内容中,实际上
Option<T>
应该是可能的!)。此外,这消除了将您拥有的任何内容转换为
Vec
的需要,而且,在应用一些迭代器修饰符后,不需要
.collect()
!所以它也应该更快!

我错过了什么还是应该这样做?

arrays vector iterator rust
1个回答
12
投票

您所描述的此类函数通常应采用

IntoIterator<Item = T>
;因此它可以接受
Iterator<T>
Vec<T>
作为输入。

这也可以与其他技术相结合;例如,此方法

concat
将接受
&[&str]
(因此通过自动解引用/引用强制转换为
&Vec<&str>
)、
&[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
}

(这个具体的例子实际上通常更适合

Concat
,因为它能够计算出最终结果的长度,从而一次性分配正确长度的字符串。但这只是一个证明概念以及如何组合多种花哨的技术。)

© www.soinside.com 2019 - 2024. All rights reserved.