Reputation: 23
In module db.rs , while reading the value from the DataBase, i got the Error temporary value dropped while borrowed
consider using a let
binding to create a longer lived value
use bytes::Bytes;
use std::collections::HashMap;
use std::sync::{Arc, Mutex};
#[derive(Clone, Debug)]
pub struct Db {
// pub entries: Arc<bool>,
pub entries: Arc<Mutex<HashMap<String, Bytes>>>,
}
impl Db {
pub fn new() -> Db {
Db {
entries: Arc::new(Mutex::new(HashMap::new())),
}
}
/// Reads data from the database
pub fn read(&mut self, arr: &[String]) -> Result<Bytes, &'static str> {
let key = &arr[1];
let query_result = self.entries.lock().unwrap().get(key);// Error in this Line.
if let Some(value) = query_result {
return Ok(Bytes::from("hello"));
} else {
return Err("no such key found");
}
}
}
but when i modify the code and trying to get the value in the next line, it didn't give any error.
let query_result = self.entries.lock().unwrap();
let result = query_result.get(key);
can anyone help me understand what's going on under the hood?
Upvotes: 1
Views: 674
Reputation: 6651
We can see why Rust thinks this is an error by checking how Mutex::lock
works. If successful, it doesn't return a reference directly, it returns a MutexGuard
struct that can deref into the type it wraps, a HashMap
in your case.
The signature of Deref::deref<Target = T>
is (with the elided lifetimes added):
fn deref<'a>(&'a self) -> &'a T
This means that the MutexGuard
can only give us a reference to the HashMap
inside for as long as it is itself alive (the lifetime 'a
). But because you never store it anywhere, instead dereferencing it directly, Rust thinks that it gets dropped right after the call to get
. But you keep the result of get
around, which can only live for as long as the reference to the HashMap
passed into it, which in turn only lives as long as the MutexGuard
which gets dropped immediately.
If you store the MutexGuard
, on the other hand, like
let guard = self.entries.lock().unwrap();
let query_result = guard.get(key);
it only gets dropped at the end of the scope, so any references it gave out are also valid until the end of the scope.
Upvotes: 2