在 serde_json 的 crate 文档中的示例(将 JSON 解析为 Rust 结构),省略了错误处理:
use serde::{Deserialize, Serialize};
use serde_json::Result;
#[derive(Serialize, Deserialize)]
struct Person {
name: String,
age: u8,
phones: Vec<String>,
}
fn typed_example() -> Result<()> {
// Some JSON input data as a &str. Maybe this comes from the user.
let data = r#"
{
"name": "John Doe",
"age": 43,
"phones": [
"+44 1234567",
"+44 2345678"
]
}"#;
// Parse the string of data into a Person object. This is exactly the
// same function as the one that produced serde_json::Value above, but
// now we are asking it for a Person as output.
let p: Person = serde_json::from_str(data)?;
// Do things just like with any other Rust data structure.
println!("Please call {} at the number {}", p.name, p.phones[0]);
Ok(())
}
from_string()
的作用由分配的 target 的类型控制。
在实践中,我们必须处理错误。所以,自然要做的是:
match p: Person = serde_json::from_str(data) {
// ...
}
但这在比赛结构中是不允许的。
match serde_json::from_str(data) {
// ...
}
始终返回空类型“()”。
我的情况涉及许多嵌套匹配结构,所以我不想使用首先分配给变量的明显解决方案。
如何控制匹配结构中所需的目标表达式类型?
在您给出的示例中,错误处理被推迟给调用者:
let p: Person = serde_json::from_str(data)?;
注意末尾的
?
:这意味着如果出现错误,函数应立即返回并传播错误。
如果你想在本地处理错误,你需要使用
match
,但你不能使用match p: Person = serde_json::from_str(data) { /* ... */ }
,因为from_str
不会返回Person
。你需要做的是:
let p: Person = match serde_json::from_str (data) {
Ok (p) => p,
Err (_) => Person { name: "John Doe".into(), age: 42, phones: vec![] },
}
正如 Herohtar 所提到的,语法
match p: Person = serde_json::from_str(data) { /* ... */ }
无效,但你可以这样做
let p: Person = match serde_json::from_str(data)? {
// ...
}
另一种选择是涡轮鱼:
let p = match serde_json::from_str::<Person>(data) {
// ...
}