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

Yub*_*773 5 rust option-type

我试图使这种转换Option<Option<String>>成为Option<Option<&str>>可能,但在尝试了许多方法(包括使用.map.

我知道转换是可能的,但是,如果没有嵌套Option(即Option<String>Option<&str>):只需使用.as_deref().
使用.map(|inner| inner.as_deref())侵犯了所有权。

bk2*_*204 8

使用 plain 违反所有权规则的原因map是因为它需要self. 你正在消耗外部Option,然后试图从内部借用一些东西,这是行不通的。

然而,这里有一个简单的方法,使用as_ref然后as_derefmap. as_ref变成&Option<T>, Option<&T>where Tis Option<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);
}
Run Code Online (Sandbox Code Playgroud)


Kev*_*eid 5

当您发现自己将多个方法和闭包串在一起以使用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,
    }
}
Run Code Online (Sandbox Code Playgroud)

这样做的好处是读起来意思很明显;它的实际作用是毫无疑问的。如果需要对其进行更改以执行稍微不同的操作,那么如何操作是显而易见的。

它并不总是更好(这个特定的例子在所有重复中特别不雅),但(在我看来)它总是值得考虑的选择。