我有以下不编译的代码.
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
.
请注意,这是一个简化的示例.实际上我不能先反转两个链然后再拉链.
你正在寻找以下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
,所以它仍然无效.
另一种选择(可能不是唯一的)是将链收集到一个载体中.由于内存分配不好,但如果它不是一个性能瓶颈,那么值得进行权衡.
归档时间: |
|
查看次数: |
199 次 |
最近记录: |