I'm trying to develop a message routing app. I've read the official Rust docs and some articles and thought that I got how pointers, owning, and borrowing stuff works but realized that I didn't.
use std::collections::HashMap;
use std::vec::Vec;
struct Component {
address: &'static str,
available_workers: i32,
lang: i32
}
struct Components {
data: HashMap<i32, Vec<Component>>
}
impl Components {
fn new() -> Components {
Components {data: HashMap::new() }
}
fn addOrUpdate(&mut self, component: Component) -> &Components {
if !self.data.contains_key(&component.lang) {
self.data.insert(component.lang, vec![component]);
} else {
let mut q = self.data.get(&component.lang); // this extra line is required because of the error: borrowed value does not live long enough
let mut queue = q.as_mut().unwrap();
queue.remove(0);
queue.push(component);
}
self
}
}
(Also available on the playground)
Produces the error:
error: cannot borrow immutable borrowed content `**queue` as mutable
--> src/main.rs:26:13
|
26 | queue.remove(0);
| ^^^^^ cannot borrow as mutable
error: cannot borrow immutable borrowed content `**queue` as mutable
--> src/main.rs:27:13
|
27 | queue.push(component);
| ^^^^^ cannot borrow as mutable
Could you please explain the error and it would be great if you can give me the right implementation.
Here is an MCVE of your problem:
Before NLL
After NLL
Many times, when something seems surprising like this, it's useful to print out the types involved. Let's print out the type of
queue
:We have a mutable reference to an immutable reference to a
Vec<u8>
. Because we have an immutable reference to theVec
, we cannot modify it! Changingself.data.get
toself.data.get_mut
changes the type to&mut &mut collections::vec::Vec<u8>
and the code compiles.If you want to implement the concept of "insert or update", you should check into the
entry
API, which is more efficient and concise.Beyond that, Rust uses
snake_case
for method naming, notcamelCase
.