Hey there! Apologies if this has already been covered – I am extremely new to rust, so this is probably a pretty elementary question. I have a simplified example of an "upsert" function which runs exactly as expected.
use std::collections::BTreeMap;
#[derive(Debug)]
struct Thing {
name: String,
version: u8
}
fn upsert(map: &mut BTreeMap<char, Thing>, id: char, name: String) {
// perform an update
if !match map.get_mut(&id) {
Some(thing) => {
thing.name = name.clone();
thing.version = thing.version + 1;
true
},
None => false
}
// perform an insert
{
map.insert(id, Thing{ name: name.clone(), version: 1 });
}
}
fn main(){
let mut map: BTreeMap<char, Thing> = BTreeMap::new();
map.insert('a', Thing{ name: "Alpha".to_string(), version: 1});
map.insert('b', Thing{ name: "Beta".to_string(), version: 1});
map.insert('d', Thing{ name: "Delta".to_string(), version: 1});
// performs an update
upsert(&mut map, 'b', "Bravo".to_string());
// performs an insert
upsert(&mut map, 'c', "Charlie".to_string());
println!("{:?}", map);
}
however, I initially wanted (and would still prefer) to write the upsert
function without those booleans, which feel really clunky when the following should (based on my understanding) be safe:
fn upsert(map: &mut BTreeMap<char, Thing>, id: char, name: String) {
// perform an update
if let Some(thing) = map.get_mut(&id) {
thing.name = name.clone();
thing.version = thing.version + 1;
}
// perform an insert
else {
map.insert(id, Thing{ name: name.clone(), version: 1 });
}
}
However, this throws an Error: cannot borrow `*map` as mutable more than once at a time...
at the map.insert
. It appears that the lifetime of thing
ends when upsert
ends; but shouldn't it end when the conditional expression ends? The variable isn't available outside that expression:
fn upsert(map: &mut BTreeMap<char, Thing>, id: char, name: String) {
// perform an update
if let Some(thing) = map.get_mut(&id) {
thing.name = name.clone();
thing.version = thing.version + 1;
}
// Error: unresolved name `thing`...
thing;
}
Am I totally missing something here? Thanks in advance!