简体   繁体   中英

Getting a read-only version of an Arc<RwLock<Foo>>?

I have an Arc<RwLock<Foo>> .

Is there a way to make something out of this, on which the RwLock 's write() does not exist? ie Is there some form of RLock which I can make from an RwLock .

Use case: I have a Foo . More than one part of my code needs to mutate the Foo (hence the RwLock), but the majority of my code must only ever have read-only access to the Foo.

Is there a way of achieving this? Or is there a way of doing this without RwLock ?

Write your own struct that contains the Arc<RwLock<Foo>> .

#[derive(Clone, Debug)]
pub struct FooReadOnly(Arc<RwLock<Foo>>);

impl FooReadOnly {
    pub fn read(&self) -> LockResult<RwLockReadGuard<'_, Foo>> {
        self.0.read()
    }

}

(A fully fleshed-out version would also contain a wrapper for try_read() .)

The general pattern worth noting here is: instead of your data type being visibly inside an Arc<RwLock<...>> , your public type contains the Arc . This allows much more flexibility in what kind of “handles” you can offer than exposing the Arc. This is a fairly common pattern in Rust — if you've ever used a library type that notes you can clone it and get another handle to the same thing, there's a good chance it's doing the same thing inside (if it's not actually a handle to an OS resource like a file descriptor).

If you wanted to fully hide the implementation details, you would also wrap the RwLockReadGuard — all it needs to do is implement Deref<Target = Foo> and forward that to the guard. Such wrappers can also do things like Deref ing to some part of the Foo rather than an &Foo exactly.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM