我有以下不编译的代码。
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);
}
得到如下错误:
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)
我的理解是rev()
方法在Iterator
中定义为实现特征的DoubleEndedIterator
fn rev(self) -> Rev<Self> where Self: DoubleEndedIterator { ... }
同样Zip
实现了这个特性:
impl<A, B> DoubleEndedIterator for Zip<A, B> where B: DoubleEndedIterator + ExactSizeIterator, A: DoubleEndedIterator + ExactSizeIterator
问题是Chain
没有实现ExactSizeIterator
。但是我该如何解决这个问题?
我尝试为两个链添加.take()
以将类型转换为实现Take
的{{1}},但请勿实现ExactSizeIterator
。
请注意,这是一个简化的示例。实际上,我不能先反转两个链,然后再拉链。
答案 0 :(得分:8)
您正在寻找以下impl(剧透:它不存在):
impl<A, B> ExactSizeIterator for Chain<A, B>
where A: ExactSizeIterator, B: ExactSizeIterator { ... }
ExactSizeIterator
必须只实现一种方法len(&self)
。因此,假设实现背后的想法是将两个长度相加以便chain_a_b.len() == a.len() + b.len()
。
reason it doesn't exist是Rust无法保证此添加(usize + usize
)不会溢出。因此它禁止它。听起来有点严格,但不幸的是,这是现在的现状。
更糟糕的是:即使这个impl确实存在,你也会遇到Chars
不是ExactSizeIterator
的事实,所以它仍然无效。
替代方案(可能不是唯一的方法)是将链条收集到矢量中。由于内存分配不好,但如果它不是一个性能瓶颈,那么值得进行权衡。