rust - 如何从包装在 Arc 中的 Hashmap 和 Rust 中的 Mutex 返回对值的引用?
问题描述
我在返回HashMap<String,String>
由 Arc 和 Mutex 包装以在线程之间共享的值的引用时遇到了一些麻烦。代码是这样的:
use std::sync::{Arc,Mutex};
use std::collections::HashMap;
struct Hey{
a:Arc<Mutex<HashMap<String, String>>>
}
impl Hey {
fn get(&self,key:&String)->&String{
self.a.lock().unwrap().get(key).unwrap()
}
}
如上图,代码因为returns a value referencing data owned by the current function
. 我知道lock()
返回 MutexGuard 这是一个局部变量。但是我怎样才能实现这种方法来获取对 HashMap 中值的引用。如果我不能,Rust 禁止这样做的动机是什么?
解决方案
让我解释一下为什么 rustc 认为你的代码是错误的。
- 只有当您锁定了受 Mutex 保护的值时,您才能与它进行交互。
- 由 RAII 警卫处理的锁。
所以,我对你的代码脱糖:
fn get(&self,key:&String)->&String{
let lock = self.a.lock().unwrap();
let reference = lock.get(key).unwrap();
drop(lock); // release your lock
// We return reference to data which doesn't protected by Mutex!
// Someone can delete item from hashmap and you would read deleted data
// Use-After-Free is UB so rustc forbid that
return reference;
}
可能您需要Arcs
用作值:
#[derive(Default)]
struct Hey{
a:Arc<RwLock<HashMap<String, Arc<String>>>>
}
fn get(&self,key:&String)->Arc<String>{
self.a.lock().unwrap().get(key).unwrap().clone()
}
PS 此外,您可以使用Arc<str>
(我会推荐),这将使您免于额外的指针间接。它可以从 String:let arc: Arc<str> = my_string.into();
或Arc::from(my_string)
推荐阅读
- amazon-s3 - Failing to read data from s3 to a spark dataframe in Sagemaker
- docker - Docker compose spring boot redis connection issue
- cassandra - Cassandra 读取超时的正确行为是什么?
- python - 我需要让表单错误显示在我的引导模式模板上
- java - 从 CSV 文件解析错误
- javascript - 在同一个 iframe 上打开 HTTPS 网站
- image - 具有多列的列表视图
- performance - 为什么 Pylint 太慢,而 pep8 只需要一秒钟来检查相同的代码?
- r - 使用 R 中的 ggscatter 按组着色
- python - Python 3:MimeMessage 创建、工作和不工作取决于电子邮件系统