【问题标题】:cannot borrow `*` as immutable because `*self` is also borrowed as mutable [E0502]不能将 `*` 作为不可变借用,因为 `*self` 也作为可变借用 [E0502]
【发布时间】:2015-11-15 20:48:56
【问题描述】:

这是我所有的代码:

use std::collections::HashMap;

pub struct Book<'a> {
    page: Vec<&'a str>,
    histories: HashMap<&'a str, &'a str>,
}

impl<'a> Book<'a> {
    pub fn new(page: Vec<&'a str>) -> Book<'a> {
        let histories = HashMap::new();
        Book {
            page: page,
            histories: histories
        }
    }

    pub fn process(&mut self, line: &str, book_id: &'a str) {

        let page_c = self.get_page(book_id);
        println!("page_c {}", page_c);

        for history in self.histories.iter() {
            println!("histories...");
        }
    }

    fn get_page(&mut self, book_id: &'a str) -> &str {
        if !self.histories.contains_key(book_id) {
            println!("not history found for book {}", book_id);
            self.histories.insert(book_id, "history A");
        }
        self.histories.get(book_id).unwrap()
    }
}

fn main() {
    println!("Hello, world!");
    let mut pages = Vec::new();
    let st = "page1";
    pages.push(st);

    let mut biblio = Book::new(pages);

    let sentence = "this is a line of page";
    let book_id = "onebook";
    biblio.process(sentence, book_id);
}

这不能编译:

src/main.rs:22:24: 22:38 error: cannot borrow `self.histories` as immutable because `*self` is also borrowed as mutable [E0502]
src/main.rs:22         for history in self.histories.iter() {
                                      ^~~~~~~~~~~~~~
src/main.rs:19:22: 19:26 note: previous borrow of `*self` occurs here; the mutable borrow prevents subsequent moves, borrows, or modification of `*self` until the borrow ends
src/main.rs:19         let page_c = self.get_page(book_id);
                                    ^~~~
src/main.rs:25:6: 25:6 note: previous borrow ends here
src/main.rs:17     pub fn process(&mut self, line: &str, book_id: &'a str) {
...
src/main.rs:25     }
                   ^
error: aborting due to previous error
Could not compile `tempo`.

我理解错误消息,但在研究和阅读similar questions 之后,我不明白如何修复我的代码。

【问题讨论】:

  • Stack Overflow 不是代码编写(或修复)服务。既然您声明您理解错误消息并发现了类似的问题,您能否就我们如何帮助您理解问题而不只是为您编写解决方案提供任何指导?上一个问题和答案有什么不足?
  • 还有很多问题都在问同样的问题。基本上所有侧边栏中的“相关”问答都应该检查出来。

标签: rust


【解决方案1】:

修复代码的最简单方法是不要为 page_c 引入额外的变量,而是直接使用来自 get_page 的结果:

pub fn process(&mut self, line: &str, book_id: &'a str) {
    println!("page_c {}", self.get_page(book_id));

    for history in self.histories.iter() {
        println!("histories...");
    }
}

这样,当您进入for 循环时,self 不会被借用,因为它仅在调用println 时被借用。如果您确实想为 page_c 提供一个变量,您可以在额外的范围内引入它,因此借用将在范围的末尾(因此在循环之前):

pub fn process(&mut self, line: &str, book_id: &'a str) {
    {
        let page_c = self.get_page(book_id);
        println!("page_c {}", page_c);
    } // page_c ceases to exist here, so the borrow of self ends
    for history in self.histories.iter() {
        println!("histories...");
    }
}

【讨论】:

  • 感谢您的回答。我需要在循环后使用page_c,类似:} // end of loop println!("page_c {}", page_c); }
猜你喜欢
  • 2015-09-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多