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)
您的选择很多。
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)
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)