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

问题描述 投票:0回答:3

有没有办法从

Option
中“提取”数据?我有一个返回
Some(HashMap)
的 API 调用。我想使用
HashMap
就好像它不在里面
Some
和玩数据。

根据我的阅读,看起来

Some(...)
只适用于匹配比较和一些内置函数。

从板条箱文档中提取的简单 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(())
}

结果:

Some("75.69.138.107")
rust enums pattern-matching option-type
3个回答
22
投票
if let Some(origin) = resp.get("origin") {
    // use origin
}

如果你能保证这个值不可能是

None
,那么你可以使用:

let origin = resp.get("origin").unwrap();

或:

let origin = resp.get("origin").expect("This shouldn't be possible!");

而且,因为你的函数返回一个

Result

let origin = resp.get("origin").ok_or("This shouldn't be possible!")?;

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

let origin = resp.get("origin").ok_or(MyError::DoesntExist)?;

10
投票

最常见的方式是用

if let

if let Some(origin) = resp.get("origin") {
    origin.do_stuff()
}

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

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

您也可以使用

unwrap
,这将为您提供期权的基础价值,或者
panic
如果它是
None

let origin = resp.get("origin").unwrap();

您可以使用

panic
自定义
expect
消息:

let origin = resp.get("origin").expect("Oops!");

或者使用

unwrap_or
计算默认值:

let origin = resp.get("origin").unwrap_or(&String::from("192.168.0.1"));

你也可以返回一个错误而不是恐慌:

let origin = resp.get("origin").ok_or(Error::UnknownOrigin)?;

7
投票

你的选择很多。

if let Some(origin) = resp.get("origin") {
    // do stuff using origin
}
origin = resp.get("origin").unwrap()
// will panic if None
resp.get("origin").map(|origin| {
    // do stuff using inner value, returning another option
})
resp.get("origin").and_then(|origin| {
    // same as map but short-circuits if there is no inner value
})
© www.soinside.com 2019 - 2024. All rights reserved.