rust - 如何返回包含 serde_json::Value 的结果?
问题描述
这就是我所拥有的,但我想避免unwrap
在我的 reqwest 值上使用:
extern crate base64;
extern crate reqwest;
use serde_json;
use serde_json::json;
pub fn perform_get(id: String) -> serde_json::value::Value {
let client = reqwest::Client::builder().build().unwrap();
let url = String::from("SomeURL");
let res = client.get(&url).send().unwrap().text();
let mut v = json!(null);
match res {
Ok(n) => {
v = serde_json::from_str(&n).unwrap();
}
Err(r) => {
println!("Something wrong happened {:?}", r);
}
}
v
}
fn main() {
println!("Hi there! i want the function above to return a result instead of a Serde value so I can handle the error in main!");
}
解决方案
官方的 Rust 书籍The Rust Programming Language可在线免费获得。它有一整章是关于 usingResult
的,解释了诸如Result
枚举之类的介绍性主题以及如何使用它。
如何返回一个
Result
包含一个serde_json::Value
?
与返回任何类型Result
的a 相同;没有什么特别的:Value
use serde_json::json; // 1.0.38
pub fn ok_example() -> Result<serde_json::value::Value, i32> {
Ok(json! { "success" })
}
pub fn err_example() -> Result<serde_json::value::Value, i32> {
Err(42)
}
如果您有一个返回 a 的函数Result
,您可以使用问号运算符 ( ?
) 在出错时提前退出函数,返回错误。这是避免unwrap
or的简洁方法expect
:
fn use_them() -> Result<(), i32> {
let ok = ok_example()?;
println!("{:?}", ok);
let err = err_example()?;
println!("{:?}", err); // Never executed, we always exit due to the `?`
Ok(()) // Never executed
}
这只是一个基本的例子。
应用于您的MCVE,它看起来像:
use reqwest; // 0.9.10
use serde_json::Value; // 1.0.38
type Error = Box<dyn std::error::Error>;
pub fn perform_get(_id: String) -> Result<Value, Error> {
let client = reqwest::Client::builder().build()?;
let url = String::from("SomeURL");
let res = client.get(&url).send()?.text()?;
let v = serde_json::from_str(&res)?;
Ok(v)
}
在这里,我使用trait 对象 Box<dyn std::error::Error>
来处理任何类型的错误(非常适合快速程序和示例)。然后,我会?
在每个可能失败的方法上(即返回 a Result
)并以明确Ok
的最终值结束函数。
请注意,可以使用此样式删除thepanic
和从未使用的值。null
也可以看看:
- 这个问号运算符是关于什么的?
- Rust 正确的错误处理(使用问号自动从一种错误类型转换为另一种错误类型)
- 来自 fn 的 Rust 返回结果错误
- 从匹配返回值到 Err(e)
- 处理/展开嵌套 Result 类型的惯用方法是什么?
更好的做法是返回一个
Result
也可以看看:
推荐阅读
- database - 是否有任何数据类型可以在 postgresql 中将变量声明为常量?
- azure - 部署不同版本的应用服务时,何时使用部署槽与单独的应用服务
- r - 'Can't use `!!!` at top level.' 是什么意思?是什么意思以及如何解决?
- ethereum - Metamask (Chrome) web3.js 控制台:ETH 交易问题(同步方法)+ web3.version
- python - Flask中路由/映射URL的理解
- email - 如何使用 GMail Addons 通过代码发送当前正在编写的电子邮件
- go - 使用 ConsumerGroup 的 Sarama 分区消费者
- json - 在 JSON 中反序列化数组中的数组
- apify - @apify/scraper-tool 中 logPerformance 的源代码在哪里
- node.js - 开玩笑 - 测试异步默认导出