Rust `borrow_mut`, `borrow_mut` 并移动

Rust `borrow_mut`, `borrow_mut` and move

我的密码是

struct Test<Source>
where
    Source: Iterator<Item = char>,
{
    source: Source,
}

impl<Source: Iterator<Item = char>> Test<Source> {
    fn read(&mut self) {
        while let Some(item) = self.source.next() {
            match item {
                '#' => self.read_head(),
                _ => {}
            }
            println!("Handled char {}", item);
        }
    }

    fn read_head(&mut self) {
        println!("Start read heading");
        let source = self.source.borrow_mut();
        let level = source.take_while(|&char| char == '#').count();
        println!("Done, level is {}", level);
    }
}

fn main() {
    let str = "##### Hello World".to_string();
    let str = str.chars().into_iter();
    let mut test = Test { source: str };
    test.read();
}

效果不错。但是在这一行中:

let source = self.source.borrow_mut();

如果将 borrow_mut 更改为 borrow,将产生错误:

error[E0507]: cannot move out of `*source` which is behind a shared reference
  --> src/main.rs:24:21
   |
24 |         let level = source.take_while(|&char| char == '#').count();
   |                     ^^^^^^ move occurs because `*source` has type `Source`, which does not implement the `Copy` trait

所以为什么 borrow_mut 有效但不能借用。 moveborrow.

之间的关系我不是很清楚

So why borrow_mut works but borrow not.

因为there is an implementation of Iterator for exclusive references to iterators:

impl<'_, I> Iterator for &'_ mut I where I: Iterator + ?Sized

这意味着对迭代器的独占引用 本身就是一个迭代器,并且可以“按原样”使用(顺便说一句,这就是为什么 Iterator::by_ref 是一个东西,有用)。

I don't have a clear understanding about relation between move and borrow.

本身并没有一个,只是在这种情况下,对迭代器的可变引用也是一个迭代器(就其本身而言),这意味着它满足 take_while 的要求按值获取迭代器:

pub fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P> where P: FnMut(&Self::Item) -> bool

共享引用不是这样,因此会触发您看到的错误。