use std::{collections::VecDeque, collections::HashMap, sync::Arc};
use tokio::sync::Mutex;
struct Employee {
name: String,
old: u32,
}
struct Department{
employees: Arc<Mutex<VecDeque<Employee>>>,
}
struct Company{
Departments: Arc<Mutex<HashMap<u32, Department>>>, //DepartmentID: u32
}
impl Company {
pub async fn get_department(&self, id: u32) -> Option<&Department>{
let mut department = self.Departments.lock().await;
department.get(&id) // err: cannot return value referencing local variable `department` returns a value referencing data owned by the current function
}
}
#[tokio::main]
async fn main(){
let company = Company { Departments: Arc::new(Mutex::new(HashMap::new())), };
let department1 = company.get_department(1);
}
You can't. If you need to access something inside Mutex
, you have to return the MutexGuard
.
So, what is solutions to return &Department value?. I want to get a department in company by id
You can't. A reference to the inside of the mutex can't live longer than the MutexGuard
that you get from locking. So you have to return the guard object instead and then use that to get to the Department data.
You might have better luck if you use a proper concurrent hashmap like dashmap instead of Mutex<HashMap<_>
, though i think it also works through guard objects that you'd have to return.
Since you're using tokio
's Mutex
you could use MutexGuard::try_map
to map the MutexGuard
Since your department type is reference counted with an Arc
, you could just clone it to get another shared handle to the same value and return the clone.
You can return Department
(owned copy), or Box<Department>
if you want to return it by pointer. You can return Arc<Department>
if you want to return a shared reference that isn't temporary. Mutex<HashMap<K, Arc<V>>
is a common pattern in such case.
But you can't return a temporary unprotected borrow of a mutex-protected value. This is literally unsafe — some other thread/future could mutate the HashMap
and change or remove the Department
as soon as the MutexGuard
is dropped, leaving you with a data race or a dangling pointer. In this case it's not a limitation of the borrow checker, but you have an actual concurrency bug in your code that the compiler is catching.
This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.