pub trait Skip<I: Iterator> {
fn skip(&mut self, steps: usize);
}
impl<I: Iterator> Skip<I> for I {
fn skip(&mut self, mut steps: usize) {
for _ in self {
steps -= 1;
if steps <= 0 {
break;
}
}
}
}
fn main() {
let s = "abc123def";
let mut chars = s.chars();
chars.skip(2);
println!("{:?}", chars.collect::<String>());
}
Run Code Online (Sandbox Code Playgroud)
错误:
pub trait Skip<I: Iterator> {
fn skip(&mut self, steps: usize);
}
impl<I: Iterator> Skip<I> for I {
fn skip(&mut self, mut steps: usize) {
for _ in self {
steps -= 1;
if steps <= 0 {
break;
}
}
}
}
fn main() {
let s = "abc123def";
let mut chars = s.chars();
chars.skip(2);
println!("{:?}", chars.collect::<String>());
}
Run Code Online (Sandbox Code Playgroud)
可以通过获取可变引用来移动值吗?
不。引用不会移动被引用的项目。这是一大参考。
但是,Iterator::skip
确实获得了迭代器的所有权,这是一个举动:
fn skip(self, n: usize) -> Skip<Self>
Run Code Online (Sandbox Code Playgroud)
要解决该错误,您可以...获取可变引用!
chars.by_ref().skip(2);
Run Code Online (Sandbox Code Playgroud)
但是,请注意,在不使用它的情况下调用迭代器适配器没有任何作用:
警告:必须使用的未使用结果:迭代器适配器是懒惰的,除非被消耗,否则什么都不做
这里真正的问题是你没有打电话给skip
你认为你是。如果您将方法重命名为skip2
,您将看到它按预期工作。
这是因为方法查找更喜欢在 by-mutable-reference ( )之前接受接收者 by-value ( self
) 之前 by &self
-reference ( &mut self
) 的方法。
选择与标准库相同的方法名称可能是一个坏主意,尤其是对于迭代器,但令人惊讶的是没有打印警告说在范围内有多个适用的方法。
您可以使用通用函数调用语法 (UFCS)来指定要调用的实现:
pub trait Skip: Iterator {
fn skip(&mut self, steps: usize) {
for _ in self.take(steps) {}
}
}
impl<I> Skip for I where I: Iterator {}
fn main() {
let s = "abc123def";
let mut chars = s.chars();
Skip::skip(&mut chars, 2);
println!("{:?}", chars.collect::<String>());
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1408 次 |
最近记录: |