如何从 Option 中提取数据以供独立使用?

sea*_*mus 3 enums pattern-matching optional rust

有没有办法“拉”出数据Option?我有一个 API 调用返回Some(HashMap). 我想使用HashMap它,就好像它不在里面一样Some并使用数据。

根据我所阅读的内容,它看起来Some(...)仅适用于匹配比较和一些内置函数。

从 crate 文档中提取的简单 API 调用:

use std::collections::HashMap;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let resp = reqwest::blocking::get("https://httpbin.org/ip")?
        .json::<HashMap<String, String>>()?;
    println!("{:#?}", resp.get("origin"));
    Ok(())
}
Run Code Online (Sandbox Code Playgroud)

结果:

Some("75.69.138.107")
Run Code Online (Sandbox Code Playgroud)

Ibr*_*med 10

最常见的方法是if let

if let Some(origin) = resp.get("origin") {
    origin.do_stuff()
}
Run Code Online (Sandbox Code Playgroud)

为了更细粒度的控制,您可以使用模式匹配:

if let Some(origin) = resp.get("origin") {
    origin.do_stuff()
}
Run Code Online (Sandbox Code Playgroud)

您还可以使用unwrap,这将为您提供期权的基础价值,或者panic如果是None

let origin = resp.get("origin").unwrap();
Run Code Online (Sandbox Code Playgroud)

您可以使用panic以下命令自定义消息expect

let origin = resp.get("origin").expect("Oops!");
Run Code Online (Sandbox Code Playgroud)

或者使用以下方法计算默认值unwrap_or

match resp.get("origin") {
    Some(origin) => origin.do_stuff(),
    None => panic!("origin not found!")
}
Run Code Online (Sandbox Code Playgroud)

您还可以返回错误而不是恐慌:

let origin = resp.get("origin").unwrap();
Run Code Online (Sandbox Code Playgroud)


Iva*_*n C 8

您的选择很多。

if let Some(origin) = resp.get("origin") {
    // do stuff using origin
}
Run Code Online (Sandbox Code Playgroud)
origin = resp.get("origin").unwrap()
// will panic if None
Run Code Online (Sandbox Code Playgroud)
resp.get("origin").map(|origin| {
    // do stuff using inner value, returning another option
})
Run Code Online (Sandbox Code Playgroud)
resp.get("origin").and_then(|origin| {
    // same as map but short-circuits if there is no inner value
})
Run Code Online (Sandbox Code Playgroud)


Pet*_*all 6

if let Some(origin) = resp.get("origin") {
    // use origin
}
Run Code Online (Sandbox Code Playgroud)

如果您可以保证值不可能为None,那么您可以使用:

let origin = resp.get("origin").unwrap();
Run Code Online (Sandbox Code Playgroud)

或者:

let origin = resp.get("origin").expect("This shouldn't be possible!");
Run Code Online (Sandbox Code Playgroud)

而且,由于您的函数返回一个Result

let origin = resp.get("origin").ok_or("This shouldn't be possible!")?;
Run Code Online (Sandbox Code Playgroud)

或者使用自定义错误类型:

let origin = resp.get("origin").ok_or(MyError::DoesntExist)?;
Run Code Online (Sandbox Code Playgroud)