Rust: Как установить желаемый тип возврата в структуре соответствия? - PullRequest
0 голосов
/ 21 февраля 2020

В примере в документации к ящику serde_ json (синтаксический анализ 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 (), контролируется типом цель назначения.

На практике мы должны обработать ошибку. Итак, естественное, что нужно сделать:

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

, но это не разрешено в структуре соответствия.

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

всегда возвращает пустой тип "()".

В моей ситуации могут использоваться вложенные структуры соответствия, поэтому я не хотел бы использовать очевидное решение о присвоении переменной в первую очередь.

Итак, как мне управлять желаемым целевым типом выражения в структуре соответствия ?

Ответы [ 2 ]

2 голосов
/ 21 февраля 2020

В приведенном вами примере обработка ошибок откладывается до вызывающей стороны:

let p: Person = serde_json::from_str(data)?;

Обратите внимание на ? в конце: это означает, что в случае ошибки функция должна немедленно вернуться, передавая error.

Если вы хотите обработать ошибку локально, вам нужно использовать 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![] },
}
0 голосов
/ 21 февраля 2020

Как упоминалось в Herohtar, синтаксис match p: Person = serde_json::from_str(data) { /* ... */ } недействителен, но вы можете сделать

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

Другой вариант - turbofi sh:

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