如何在匹配结构中设置所需的返回类型?

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

在 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) {
    // ...
}

始终返回空类型“()”。

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

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

rust match serde-json
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![] },
}

3
投票

正如 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) {
    // ...
}
© www.soinside.com 2019 - 2024. All rights reserved.