正如标题所示,在 Rust 中,.rev().rev()有效, .rev().skip(1)有效,但.rev().skip(1).rev()无效。下面是演示:
// This compiles
fn main() {
let s = "Hello!";
println!("{}", &s.chars().rev().skip(1).collect::<String>());
}
Run Code Online (Sandbox Code Playgroud)
// This compiles
fn main() {
let s = "Hello!";
println!("{}", &s.chars().rev().rev().collect::<String>());
}
Run Code Online (Sandbox Code Playgroud)
// This *does not* compile
fn main() {
let s = "Hello!";
println!("{}", &s.chars().rev().skip(1).rev().collect::<String>());
}
Run Code Online (Sandbox Code Playgroud)
最后一个无法编译:
// This compiles
fn main() {
let s = "Hello!";
println!("{}", &s.chars().rev().skip(1).collect::<String>());
}
Run Code Online (Sandbox Code Playgroud)
有人可以解释为什么会出现这种情况吗?
Val*_*tin 19
调用.chars()返回一个Iterator( Chars) ,该 ( ) 实现了DoubleEndedIterator,而 using 则.rev()需要。
fn rev(self) -> Rev<Self>
where
Self: DoubleEndedIterator
Run Code Online (Sandbox Code Playgroud)
然后调用.skip()会产生一个 new Iterator( Skip) ,只有DoubleEndedIterator当Iterator(在本例中Chars)同时实现DoubleEndedIterator和 时,它才会实现ExactSizeIterator。
impl<I> DoubleEndedIterator for Skip<I>
where
I: DoubleEndedIterator + ExactSizeIterator
Run Code Online (Sandbox Code Playgroud)
然而,Chars并没有实施ExactSizeIterator。所以DoubleEndedIterator没有实现Skip. .rev()所以现在第二次调用不再满足调用的要求。
该rev方法返回一个名为的结构Rev<I>,其中I是您调用它的迭代器。
例如,
my_str.chars()获取一个Chars作为迭代器的结构。打电话.rev()给你Rev<Chars>。
.rev()要求I是 a DoubleEndedIterator(这是有道理的,反转是通过从后到前迭代来完成的)。
该skip方法返回一个名为的结构Skip<I>,其中类似地,I是您调用它的任何迭代器。
这可以在任何迭代器上调用(这是有道理的)。
然而,Skip<I>仅DoubleEndedIterator当I实现DoubleEndedIterator 和 ExactSizeIterator时才实现。
这意味着,我们只能.rev调用Skip<I>if I: DoubleEndedIterator + ExactSizeIterator。
在我们查看您所写的内容之前,最后一点:Chars实现DoubleEndedIterator 但不是 ExactSizeIterator,因为字符在以 utf8 编码时是可变长度的。
看看整个事情:
s
.chars() // DoubleEndedIterator
.rev() // DoubleEndedIterator
.skip() // Doesn't implement DoubleEndedIterator because it doesn't implement ExactSizeIterator
.rev() // Err, we need DoubleEndedIterator here.
Run Code Online (Sandbox Code Playgroud)