【问题标题】:Rust `borrow_mut`, `borrow_mut` and moveRust `borrow_mut`、`borrow_mut` 并移动
【发布时间】:2021-06-25 06:16:54
【问题描述】:

我的代码是

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之间的关系不是很清楚。

【问题讨论】:

    标签: rust move borrow-checker


    【解决方案1】:

    那么为什么borrow_mut 有效,而borrow 无效。

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

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

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

    我对@9​​87654328@和borrow之间的关系不是很清楚。

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

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

    共享引用并非如此,因此会触发您看到的错误。

    【讨论】:

    • 可能想提一下,只有可变引用迭代器的迭代器实现的原因是,推进迭代器需要改变其状态,这就是不可变借用从根本上无法工作的原因。
    猜你喜欢
    • 2022-12-01
    • 2023-01-20
    • 1970-01-01
    • 2016-07-11
    • 2015-06-11
    • 2021-11-09
    • 2019-05-01
    • 1970-01-01
    • 2022-11-27
    相关资源
    最近更新 更多