How to reverse after zip two chains

I have the following code that does not compile.

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); } 

An error has appeared, for example:

 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) 

My understanding of the rev() method is defined in Iterator as where it implements the DoubleEndedIterator property

 fn rev(self) -> Rev<Self> where Self: DoubleEndedIterator { ... } 

Zip also implements this feature:

 impl<A, B> DoubleEndedIterator for Zip<A, B> where B: DoubleEndedIterator + ExactSizeIterator, A: DoubleEndedIterator + ExactSizeIterator 

Therefore, the Chain problem does not implement ExactSizeIterator . But how do I get around this?

I tried adding .take() for both chains to convert the type to Take , which implements ExactSizeIterator , but Take does not implement DoubleEndedIterator .

Please note that this is a simplified example. In fact, I can not change both chains first, and then make zip.

+7
rust
source share
1 answer

You are looking for the following imp (spoiler: it does not exist):

 impl<A, B> ExactSizeIterator for Chain<A, B> where A: ExactSizeIterator, B: ExactSizeIterator { ... } 

An ExactSizeIterator must implement only one method, len(&self) . Thus, the idea of โ€‹โ€‹a hypothetical implementation would be to sum both lengths so that chain_a_b.len() == a.len() + b.len() .

The reason that does not exist is that Rust cannot guarantee that this add-on ( usize + usize ) will not overflow. Thus, it prohibits. It sounds a little austere, but unfortunately the status quo is now.

Worse: even if this impl actually existed, you would face the fact that Chars not an ExactSizeIterator , so it still wonโ€™t work.

An alternative (perhaps not the only one) would be combining the chains into a vector. Bad due to memory allocation, but if it's not a bottleneck in performance, it can be worth the trade-offs.

+7
source share

All Articles