// RangeInclusive编译不通过
fn main() {
for k in (1..=10).zip(1..=20).rev() {
println!("{} {}", k.0, k.1);
}
}
提示:
error[E0277]: the trait bound
RangeInclusive<i32>: ExactSizeIterator
is not satisfied
改成Range就正常:
// Range编译通过
fn main() {
for k in (1..11).zip(1..21).rev() {
println!("{} {}", k.0, k.1);
}
}
但是更奇怪的是,如果我不进行zip操作,那么无论是RangeInclusive还是Range都能编译通过。
造成这样的差异(ExactSizeIterator is not satisfied)的原因是什么?
rev 需要参数是 DoubleEndedIterator 。
而 zip 的结果 Zip<A,B> ,需要 A, B 均是 ExactSizeIterator 才会实现 DoubleEndedIterator: Zip<A,B>。因为只有两个 iterator 的长度都已知,才能确定 zip 后 iterator 的终点。
但是,RangeInclusive 只对 i8, u8, i16, u16 实现了 ExactSizeIterator 。原因是,ExactSizeIterator 有一个成员叫 len() ,返回长度。而对 u32 以上,其值会超过 usize::MAX ,无法实现。source。所以 RangeInclusive<i32> 在 zip 过之后,结果没有实现 DoubleEndedIterator ,就不能调用 rev 了。
由于 rev 本身不需要 ExactSizeIterator ,只需要 DoubleEndedIterator 就可以调用,而 RangeInclusive 实现了 DoubleEndedIterator ,所以 RangedInclusive 自己是可以调用 rev 的。
fefe的回答已经完全解释清楚,但感觉内容逻辑调整一下更好理解:
在此重新调整一下顺序并按条列出:
- rev 本身不需要 ExactSizeIterator ,只需要 DoubleEndedIterator 就可以调用
- RangeInclusive 实现了 DoubleEndedIterator
- RangeInclusive 只对 i8, u8, i16, u16 实现了 ExactSizeIterator (因为更大的类型无法实现len方法,可能会溢出usize::MAX)
- zip 的结果 Zip<A,B> A, B 均是 ExactSizeIterator 才会实现 DoubleEndedIterator: Zip<A,B>,因为只有两个 iterator 的长度都已知,才能确定 zip 后 iterator 的终点。
- 因为没有满足均是 ExactSizeIterator,zip后没有实现DoubleEndedIterator,因而无法调用rev