2

Here is all of my code:

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);
}

This doesn't compile:

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`.

I understand the error message, but after research and reading similar questions, I do not understand how I can fix my code.

Community
  • 1
  • 1
Olivier
  • 21
  • 3
  • 2
    Stack Overflow is not a code-writing (or fixing) service. Since you state you understand the error message and have found similar questions, can you give us any guidance on how we can help you understand the problem *without just writing the solution for you*? What is insufficient about the previous question and answer(s)? – Shepmaster Nov 15 '15 at 20:59
  • 2
    There's also numerous questions asking the same thing. Basically all the "Related" Q&A in the sidebar should be checked out. – Shepmaster Nov 15 '15 at 21:16

1 Answers1

1

The simplest way to fix your code is to not introduce an extra variable for page_c, but use the result from get_page directly:

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...");
    }
}

This way, self isn't borrowed when you get to the for loop, because it is only borrowed for the call to println. If you did want to have a variable for page_c, you could introduce it in an extra scope, so the borrow will at the end of the scope (and therefore before the loop):

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...");
    }
}
fjh
  • 12,121
  • 4
  • 46
  • 46
  • Thanks for your answer. I need to use ``page_c`` after the loop,something like that: ``} // end of loop println!("page_c {}", page_c); }`` – Olivier Nov 16 '15 at 04:30