Rust 取消一个弧<;RwLock<;T>&燃气轮机;返回RwLockReadGuard<;T>;默认情况下
我有以下用于Rust 取消一个弧<;RwLock<;T>&燃气轮机;返回RwLockReadGuard<;T>;默认情况下,rust,lifetime,ownership,Rust,Lifetime,Ownership,我有以下用于Arc的包装器,并且我希望在默认情况下将它们解除限制以返回RwLockReadGuard 无论如何使用:{Result,bail}; 使用serde::{反序列化,序列化}; 使用std::ops::Deref; 使用std::sync::{Arc,Mutex,RwLock,RwLockReadGuard,rwlockriteguard}; #[派生(序列化、反序列化、调试、克隆、默认)] 发布结构ArcRwLock(Arc); 脉冲弧锁{ 发布fn新(数据:T)->Self{ Ar
Arc
的包装器,并且我希望在默认情况下将它们解除限制以返回RwLockReadGuard
无论如何使用:{Result,bail};
使用serde::{反序列化,序列化};
使用std::ops::Deref;
使用std::sync::{Arc,Mutex,RwLock,RwLockReadGuard,rwlockriteguard};
#[派生(序列化、反序列化、调试、克隆、默认)]
发布结构ArcRwLock(Arc);
脉冲弧锁{
发布fn新(数据:T)->Self{
ArcRwLock(Arc::new(RwLock::new(数据)))
}
发布fn写入(&self)->结果{
匹配self.0。请尝试_write(){
正常(x)=>正常(x),
错误(e)=>{
保释(
“RwLock无法获取写入程序锁,错误:{}”,
e、 to_string()
)
}
}
}
pub fn read(&self)->RwLockReadGuard{
self.0.read().unwrap()
}
}
//ArcRwLock的impl Deref{
//类型目标=RwLockReadGuard;
//#[内联]
//fn deref(&self)->&self::Target{
//self.0.read().unwrap()
// }
// }
ArcRwLock的impl PartialEq{
fn eq(&self,其他:&self)->bool{
如果Arc::ptr_eq(&self.0,&other.0)&&&&:core::ptr::eq(&*self.0,&*other.0){
真的
}否则{
*其他.0.read().unwrap().deref()==*self.0.read().unwrap().deref())
}
}
}
我编写上面的包装器主要是为了PartialEq
我需要一个父结构来正确地#[派生(PartialEq)]
大多数时候,我都是从Arc
读取T
值,很少向其写入数据。
上述实现允许我使用以下方法读取/写入值:
some_arc_object.write()?.uuid=uuid::new_v4();
让更新的_uuid:T=some_arc_object.read().uuid;
//其中uuid是T的一个字段
由于我大部分时间都在读取属性,因此我希望消除重复的.read()
,并通过取消对整个弧的引用来实现以下目的:
let updated_uuid:T=some_arc_object.uuid;
//而不必添加.read()
//让更新的_uuid:T=some_arc_object.read().uuid;
我目前的拙劣尝试如上文注释部分所示,试图使
deref()
与.read()
的工作方式相同。但是编译器不喜欢返回局部变量的引用。是否有可能通过某种终身魔法或其他解决方法实现此目标?通过设计解除引用只应解析指向指针对象的智能指针,请参见。在Deref
中获取像MutexGuard
或RwLockReadGuard
这样的同步保护肯定超出了这一指导原则,可能会导致微妙的错误。也就是说,您可以获得资源的隐式锁定,而无需对其显式调用lock()
、read()
或write()
,因为它隐藏在解析方法调用时隐式调用的Deref
impl中
至于不可能的原因:Deref
的返回类型是一个引用,因此您需要返回一些可以从Deref()
转换为引用的内容。rBlockReadGuard
是您在deref()
范围内创建的一个值,因此它被丢弃在范围的末尾,这反过来意味着您不允许对它进行引用
有时,将需要对函数中的rBlock
值执行的任何操作都封装在函数中是符合人体工程学的,也就是说,如果它是一个字符串,有时会被写入,但大多数时候你只想读它,请定义一些方便的方法,如下所示:
struct Foo {
shared: Arc<RwLock<String>>,
}
impl Foo {
fn get_shared_str(&self) -> String {
self.shared.read().unwrap().clone()
}
}
structfoo{
共享:Arc,
}
impl-Foo{
fn获取\u共享\u str(&self)->字符串{
self.shared.read().unwrap().clone()
}
}
按设计解除引用应仅解析指向被指针的智能指针,请参见。在Deref
中获取像MutexGuard
或RwLockReadGuard
这样的同步保护肯定超出了这一指导原则,可能会导致微妙的错误。也就是说,您可以获得资源的隐式锁定,而无需对其显式调用lock()
、read()
或write()
,因为它隐藏在解析方法调用时隐式调用的Deref
impl中
至于不可能的原因:Deref
的返回类型是一个引用,因此您需要返回一些可以从Deref()
转换为引用的内容。rBlockReadGuard
是您在deref()
范围内创建的一个值,因此它被丢弃在范围的末尾,这反过来意味着您不允许对它进行引用
有时,将需要对函数中的rBlock
值执行的任何操作都封装在函数中是符合人体工程学的,也就是说,如果它是一个字符串,有时会被写入,但大多数时候你只想读它,请定义一些方便的方法,如下所示:
struct Foo {
shared: Arc<RwLock<String>>,
}
impl Foo {
fn get_shared_str(&self) -> String {
self.shared.read().unwrap().clone()
}
}
structfoo{
共享:Arc,
}
impl-Foo{
fn获取\u共享\u str(&self)->字符串{
self.shared.read().unwrap().clone()
}
}
谢谢你的回答!我不知道API指南,读了之后,我意识到了解除防护的问题。但是我可以把整个事情都写进&T吗?它还允许我直接使用某些对象.uuid
,并且似乎没有违反指导原则。通过RwLock
解除对&t
的引用是不可能的,因为这正是RwLock
和Mutex
所阻止的!只有在同步原语允许的情况下才能访问。因此,只有rBlockReadGuard
或MutexGuard
可以解除进入&T