如何在Rust中将Option&lt;Option &gt;转换< String>为Option&lt;&amp;str&gt;&gt;?

0vvn1miw  于 12个月前  发布在  其他
关注(0)|答案(2)|浏览(117)

我试图使这种转换(Option<Option<String>>Option<Option<&str>>)成为可能,但在尝试了包括使用.map在内的许多方法后仍然失败。
我知道转换是可能的,但是,如果没有嵌套的Option(即Option<String>Option<&str>):只使用.as_deref()
使用.map(|inner| inner.as_deref())违反了所有权。

pcww981p

pcww981p1#

使用普通的map违反所有权规则的原因是因为它需要self。您正在使用外部的Option,然后试图从内部借用一些东西,这是不起作用的。
然而,这里有一个简单的方法,在map中使用as_ref,然后使用as_derefas_ref&Option<T>转换为Option<&T>,其中TOption<String>,因此当您调用map时,您将获得&Option<String>,然后您可以安全地将其传递给as_deref

fn main() {
    let foo = Some(Some(String::from("abc")));
    let bar: Option<Option<&str>> = foo.as_ref().map(|r| r.as_deref());
    eprintln!("{:?}", bar);
}

字符串

carvr3hs

carvr3hs2#

当你发现自己将多个方法和闭包串在一起来使用OptionResult,甚至像hash_map::Entry这样的东西时,* 考虑 * 回到基础并使用match

pub fn opt_opt_str_ref(input: &Option<Option<String>>) -> Option<Option<&str>> {
    match input {
        Some(Some(s)) => Some(Some(s.as_str())),
        Some(None) => Some(None),
        None => None,
    }
}

字符串
这样做的好处是,当阅读时,它的含义是显而易见的;它实际上做了什么是毫无疑问的。如果需要改变它来做一些稍微不同的事情,如何做是显而易见的。
它并不总是更好的(这个特殊的例子是特别不优雅的所有重复),但(在我看来)它总是值得考虑的选择。

相关问题