I have a function that looks like:
type Attributes = HashMap<String, json::Json>;
type Store = Arc<RwLock<HashMap<String, RwLock<Attributes>>>>;
fn get(store: &Store, key: &str) -> Option<Attributes> {
store.read().iter()
.filter_map(|g| (*g).get(key) )
.filter_map(|v| v.read().ok() )
.map(|v| (*v).clone() )
.next()
}
This compiles and works just fine. However, for my own edification, I have been trying to modify this to use standard Result
/Option
methods (without converting the LockResult
to an Iter
), something like:
store.read().ok()
.and_then(|g| (*g).get(key) )
.and_then(|v| v.read().ok() )
.map(|v| (*v).clone() );
But this tells me that g does not live long enough
. I've tried adding ref
and as_ref
at various places, but can't get it to compile. What am I missing?
I know I can get it to work like:
store.read().ok()
.and_then(|g| {
(*g).get(key)
.and_then(|v| v.read().ok() )
.map(|v| (*v).clone() )
})
But I would like to be able to chain it like in the iter
case.
OK, the compiler is really messing with me tonight.
I got this incantation to compile:
fn get(store: &Store, key: &str) -> Option<Attributes> {
let r = store.read();
let x = r.as_ref().ok()
.and_then(|g| (*g).get(key) )
.and_then(|v| v.read().ok() )
.map(|v| (*v).clone() );
x
}
If you inline either r
or x
, you'll get another does not live long enough
error again. I'm not sure why, since in principle, the lock guard should remain active as a temporary until the end of the statement.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With