可以通过获取可变引用来移动值吗?

Aut*_*act 4 rust

围栏

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)

She*_*ter 5

可以通过获取可变引用来移动值吗?

不。引用不会移动被引用的项目。这是一大参考。

但是,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)