修改`iter`链以使用`and_then`等

Jac*_*own 5 rust

我有一个看起来像这样的函数:

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()
}
Run Code Online (Sandbox Code Playgroud)

这编译并且工作得很好.但是,对于我自己的启发,我一直在尝试修改它以使用标准Result/ Option方法(不转换LockResult为a Iter),类似于:

store.read().ok()
    .and_then(|g| (*g).get(key) )
    .and_then(|v| v.read().ok() )
    .map(|v| (*v).clone() );
Run Code Online (Sandbox Code Playgroud)

但这告诉我g does not live long enough.我试着加入refas_ref在不同的地方,但不能让它编译.我错过了什么?

我知道我可以像以下一样工作:

    store.read().ok()
        .and_then(|g| {
            (*g).get(key)
                .and_then(|v| v.read().ok() )
                .map(|v| (*v).clone() )
        })
Run Code Online (Sandbox Code Playgroud)

但我希望能够像在iter案件中一样链接它.

Fra*_*gné 3

好吧,编译器今晚真的很烦我。

我得到了这个咒语来编译:

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
}
Run Code Online (Sandbox Code Playgroud)

如果您内联rx,您将再次收到另一个does not live long enough错误。我不知道为什么,因为原则上,锁防护应该临时保持活动状态,直到语句结束。