如何在 .unzip() 返回的每个迭代器上使用 .collect()?

dar*_*que 5 rust

我有以下代码,其中facreturn (MyType, OtherType)

let l = (-1..13).map(|x| {
    fac(x).0
}).collect::<Vec<MyType>>();
Run Code Online (Sandbox Code Playgroud)

它有效,但我正在丢弃这些OtherType值。所以我决定使用.unzip,像这样:

let (v, r) = (-1..13).map(|x| {
    fac(x)
}).unzip();
let l = v.collect::<Vec<MyType>>();
let q = r.collect::<Vec<OtherType>>();
Run Code Online (Sandbox Code Playgroud)

但是类型推断失败了:

error: the type of this value must be known in this context
let l = v.collect::<Vec<Literal>>();
        ^~~~~~~~~~~~~~~~~~~~~~~~~~~
let q = r.collect::<Vec<OtherType>>();
        ^~~~~~~~~~~~~~~~~~~~~~~~~~~
Run Code Online (Sandbox Code Playgroud)

问题是:我不知道也不关心迭代器的具体类型是什么(我认为编译器可以推断它们,如第一个片段所示)。在这种情况下如何满足编译器?

另外,我宁愿重组的代码-我不喜欢单独通话.collect()双方vr。理想情况下,我会在 之后继续方法链.unzip()Vec在该表达式中返回两个s。

blu*_*uss 6

.unzip()不返回迭代器——它就像两个并行收集!实际上,您可以将这两部分收集到不同类型的集合中,但让我们在此示例中对两者都使用向量:

// Give a type hint to determine the collection type
let (v, r): (Vec<MyType>, Vec<OtherType>) = (-1..13).map(|x| {
    fac(x)
}).unzip();
Run Code Online (Sandbox Code Playgroud)

这样做是为了尽可能简单和透明。返回两个迭代器需要它们共享一个公共状态,这是 rust 的迭代器库倾向于避免的复杂性。

  • 避免这种情况的唯一方法是在元组迭代器上使用 `.fold()`。想象一下,如果 unzip 返回两个迭代器,它们隐藏的共享状态无论如何都必须分配和缓冲,如果您只使用其中一个部分。如果您以锁步方式使用它们,那么您不妨在一个迭代器中循环或折叠它们。 (2认同)