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

时间:2016-01-12 16:03:58

标签: 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()
}

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

store.read().ok()
    .and_then(|g| (*g).get(key) )
    .and_then(|v| v.read().ok() )
    .map(|v| (*v).clone() );

但这告诉我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() )
        })

但我希望能够像iter案例那样将其链接起来。

1 个答案:

答案 0 :(得分: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
}

如果您内嵌rx,则会再次出现另一个does not live long enough错误。我不确定为什么,因为原则上,锁定保护装置应该作为临时保持活动状态直到声明结束。