拉链两条链后如何反转

Cha*_*eng 8 rust

我有以下不编译的代码.

fn main() {
  let a =
    "123"
    .chars()
    .chain("4566".chars())
    .zip(
        "bbb"
        .chars()
        .chain("yyy".chars()))
    .rev()
    .map(|x, y| y)
    .collect::<String>();
  println!("Hello, world! {}", a);
}
Run Code Online (Sandbox Code Playgroud)

得到如下错误:

src/main.rs:37:10: 37:15 error: the trait `core::iter::ExactSizeIterator` is not implemented for the type `core::iter::Chain<core::str::Chars<'_>, core::str::Chars<'_>>` [E0277]
src/main.rs:37         .rev()
                        ^~~~~
src/main.rs:37:10: 37:15 error: the trait `core::iter::ExactSizeIterator` is not implemented for the type `core::iter::Chain<core::str::Chars<'_>, core::str::Chars<'_>>` [E0277]
src/main.rs:37         .rev()
                        ^~~~~
src/main.rs:38:10: 38:23 error: type `core::iter::Rev<core::iter::Zip<core::iter::Chain<core::str::Chars<'_>, core::str::Chars<'_>>, core::iter::Chain<core::str::Chars<'_>, core::str::Chars<'_>>>>` does not implement any method in scope named `map`
src/main.rs:38         .map(|x, y| y)
Run Code Online (Sandbox Code Playgroud)

我的理解是rev()方法被定义Iterator为实现特征的地方DoubleEndedIterator

fn rev(self) -> Rev<Self> where Self: DoubleEndedIterator { ... }
Run Code Online (Sandbox Code Playgroud)

同时Zip实现这个特性:

impl<A, B> DoubleEndedIterator for Zip<A, B> where B: DoubleEndedIterator + ExactSizeIterator, A: DoubleEndedIterator + ExactSizeIterator
Run Code Online (Sandbox Code Playgroud)

所以问题是Chain没有实现ExactSizeIterator.但是我该如何解决这个问题呢?

我试图添加.take() 两条链转换的类型Take,它实现ExactSizeIterator,但以没有实现DoubleEndedIterator.

请注意,这是一个简化的示例.实际上我不能先反转两个链然后再拉链.

mdu*_*dup 8

你正在寻找以下impl(剧透:它不存在):

impl<A, B> ExactSizeIterator for Chain<A, B>
  where A: ExactSizeIterator, B: ExactSizeIterator { ... }
Run Code Online (Sandbox Code Playgroud)

一个ExactSizeIterator必须实现只有一个方法,len(&self).因此,假设实施背后的想法是将这两个长度相加chain_a_b.len() == a.len() + b.len().

它不存在原因是Rust无法保证此addition(usize + usize)不会溢出.因此它禁止它.听起来有点严格,但不幸的是,这是现在的现状.

更糟糕的是:即使这个impl确实存在,你也会遇到Chars不是的事实ExactSizeIterator,所以它仍然无效.

另一种选择(可能不是唯一的)是将链收集到一个载体中.由于内存分配不好,但如果它不是一个性能瓶颈,那么值得进行权衡.