0

在 serde_json(将 JSON 解析为 Rust 结构)的 crate 文档中的示例中,省略了错误处理:

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()的类型控制。

在实践中,我们必须处理错误。所以,很自然的做法是:

match p: Person = serde_json::from_str(data) {
    // ...
}

但这在匹配结构中是不允许的。

match serde_json::from_str(data) {
    // ...
}

总是返回一个空类型“()”。

我的情况涉及许多嵌套匹配结构,所以我不想使用首先分配给变量的明显解决方案。

如何控制匹配结构中所需的目标表达式类型?

4

2 回答 2

5

在您给出的示例中,错误处理被推迟到调用者:

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![] },
}
于 2020-02-21T07:33:39.283 回答
1

正如 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) {
    // ...
}
于 2020-02-21T06:09:58.600 回答