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