rust使用json()

JSON 作为使用最广泛的数据结构,学习了解如何在发展最快的 Rust 语言中使用很有必要。

本文中我们将学习到:

  • 读取无类型的 JSON。
  • 将 JSON 读取为强类型数据结构。
  • 写 JSON 字符串。

使用  和  Rust 依赖。

serde
serde-json

无类型 JSON

Rust 是强类型语言,而 JSON 的并没有强制制定自己的数据类型。如果我们不关心 JSON 的数据结构,可以使用 库将 JSON 当作枚举递归使用。这个结构可以接受 bools, string, numbers, arrays, 和对象(以及 null )。

serde_json

接下来,我们给我们的新项目()添加相应依赖:

cargo new handle_json
serde_json = "1.0"
serde = { version = "1.0", features = ["derive"] }

 提供的  方法可以处理无类型 JSON 值,JSON 数据会被处理成枚举的形式。

serde_json
from_str()
use serde_json::{Value};

fn main() {
    let json = r#"
{
  "article": "how to work with json in Rust",
  "author": "tdep",
  "paragraph": [
    {
      "name": "untyped"
    },
    {
      "name": "strongly typed"
    },
    {
      "name": "writing json"
    }
  ]
}
"#;
    let parsed: Value = read_json(json);

    println!("\n\n The title of the article is {}", parsed["article"])
}

fn read_json(raw_json:&str) -> Value {
    let parsed: Value = serde_json::from_str(raw_json).unwrap();
    return parsed
}

上面代码的  函数为解析 JSON 函数,它将字符串处理成 JSON。首先使用 解析字符串,然后解包。如果我们要访问 JSON 中的字段 ,可以使用类似 这样的代码。

read_json
serde_json::from_str()
parsed["article"]

有类型的 JSON

大部分情况下,我们需要使用安全的数据类型在我们的程序中。 提供了一个很棒的方法,可以把 JSON 数据映射到 Rust 语言结构。使用方式和上一个例子相似,但是不需要使用 Enum 类型,而是分配一个原生的 Rust 数据结构。

serde

 在反序列化时可以检查 JSON 数据类型并匹配,例子如下:

serde
use serde::{Deserialize, Serialize};

#[derive(Serialize, Deserialize)]
struct Paragraph {
    name: String
}

#[derive(Serialize, Deserialize)]
struct Article {
    article: String,
    author: String,
    paragraph: Vec<Paragraph>
}

fn main() {
    let json = r#"
{
  "article": "how to work with json in Rust",
  "author": "tdep",
  "paragraph": [
    {
      "name": "untyped"
    },
    {
      "name": "strongly typed"
    },
    {
      "name": "writing json"
    }
  ]
}
"#;
    let parsed: Article = read_json_typed(json);

    println!("\n\n The name of the first paragraph is: {}", parsed.paragraph[0].name);
}

fn read_json_typed(raw_json: &str) -> Article {
    let parsed: Article = serde_json::from_str(raw_json).unwrap();
    return parsed
    
}

和第一个例子有三处不同:第一,是我们定义两个 的序列号/反序列化的结构;然后我读取 JSON 数据结构指定  对象作为类型;第三,我们读取解析结构使用的不是 Emun方式,而是  :  。

serde
Article
struct
parsed.paragraph[0].name

现在我们可以指定具体的类型和名称读JSON 内容。

但如果我们提供的 JSON 数据和结构不匹配的话:

{
  "article": "how to work with json in Rust",
  "author": "tdep",
  "paragraph": [
    {
      "name": 1
    },
    {
      "name": "strongly typed"
    },
    {
      "name": "writing json"
    }
  ]
}

我们把 JSON 中的第一个  字段改成数字,程序会出错:

name
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Error("invalid type: integer `1`, expected a string", line: 8, column: 15)', src/main.rs:44:58

或者我们把 key 改成  :

“article”
“name”
{
  "name": "how to work with json in Rust",
  "author": "tdep",
  "paragraph": [
    {
      "name": "untyped"
    },
    {
      "name": "strongly typed"
    },
    {
      "name": "writing json"
    }
  ]
}

程序也会出错:

thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Error("missing field `article`", line: 17, column: 1)', src/main.rs:44:58

因为,Rust 无法检测 JSON 中的  字段。

article

这是一种更好的接收 JSON 数据的办法。

接下来让我们看下如何反过来操作:从 Rust 数据结构到 JSON 字符串。

写JSON

我们将使用  函数将数据结构转换为 JSON 字符串,并使用 serde 的 使结构能够被序列化。 让我们看一个例子:

serde_json::to_string()
Serialize
use serde::{Deserialize, Serialize};

#[derive(Serialize, Deserialize)]
struct Paragraph {
    name: String
}

#[derive(Serialize, Deserialize)]
struct Article {
    article: String,
    author: String,
    paragraph: Vec<Paragraph>
}

fn main() {
    let article: Article = Article {
     article: String::from("how to work with json in Rust"),
     author: String::from("tdep"),
     paragraph: vec![
       Paragraph {
        name: String::from("untyped")
       },
       Paragraph {
        name: String::from("strongly typed")
       },
       Paragraph {
        name: String::from("writing json")
       }
     ]
    };

    let json = serde_json::to_string(&article).unwrap();

    println!("the JSON is: {}", json)
}

我们构建 ,然后将其引用传递给  函数。 运行 cargo 项目的结果:

Article
serde_json::to_string()
the JSON is: {"article":"how to work with json in Rust","author":"tdep","paragraph":[{"name":"untyped"},{"name":"strongly typed"},{"name":"writing json"}]}

我们已经了解了如何在 Rust 中以快速、安全和高效的方式处理 JSON。 还值得一提的是,我们使用  或  完成的每个操作,也可以使用 ,  不同的是: 序列化 (或反序列化)到一个vector,以及 到任何可写的输出(例如一个文件)。

serde_json::from_string
serde_json::to_string
serde_json::to_vec
serde_json::to_writer
to_vec
to_writer
————————

JSON 作为使用最广泛的数据结构,学习了解如何在发展最快的 Rust 语言中使用很有必要。

本文中我们将学习到:

  • 读取无类型的 JSON。
  • 将 JSON 读取为强类型数据结构。
  • 写 JSON 字符串。

使用  和  Rust 依赖。

serde
serde-json

无类型 JSON

Rust 是强类型语言,而 JSON 的并没有强制制定自己的数据类型。如果我们不关心 JSON 的数据结构,可以使用 库将 JSON 当作枚举递归使用。这个结构可以接受 bools, string, numbers, arrays, 和对象(以及 null )。

serde_json

接下来,我们给我们的新项目()添加相应依赖:

cargo new handle_json
serde_json = "1.0"
serde = { version = "1.0", features = ["derive"] }

 提供的  方法可以处理无类型 JSON 值,JSON 数据会被处理成枚举的形式。

serde_json
from_str()
use serde_json::{Value};

fn main() {
    let json = r#"
{
  "article": "how to work with json in Rust",
  "author": "tdep",
  "paragraph": [
    {
      "name": "untyped"
    },
    {
      "name": "strongly typed"
    },
    {
      "name": "writing json"
    }
  ]
}
"#;
    let parsed: Value = read_json(json);

    println!("\n\n The title of the article is {}", parsed["article"])
}

fn read_json(raw_json:&str) -> Value {
    let parsed: Value = serde_json::from_str(raw_json).unwrap();
    return parsed
}

上面代码的  函数为解析 JSON 函数,它将字符串处理成 JSON。首先使用 解析字符串,然后解包。如果我们要访问 JSON 中的字段 ,可以使用类似 这样的代码。

read_json
serde_json::from_str()
parsed["article"]

有类型的 JSON

大部分情况下,我们需要使用安全的数据类型在我们的程序中。 提供了一个很棒的方法,可以把 JSON 数据映射到 Rust 语言结构。使用方式和上一个例子相似,但是不需要使用 Enum 类型,而是分配一个原生的 Rust 数据结构。

serde

 在反序列化时可以检查 JSON 数据类型并匹配,例子如下:

serde
use serde::{Deserialize, Serialize};

#[derive(Serialize, Deserialize)]
struct Paragraph {
    name: String
}

#[derive(Serialize, Deserialize)]
struct Article {
    article: String,
    author: String,
    paragraph: Vec<Paragraph>
}

fn main() {
    let json = r#"
{
  "article": "how to work with json in Rust",
  "author": "tdep",
  "paragraph": [
    {
      "name": "untyped"
    },
    {
      "name": "strongly typed"
    },
    {
      "name": "writing json"
    }
  ]
}
"#;
    let parsed: Article = read_json_typed(json);

    println!("\n\n The name of the first paragraph is: {}", parsed.paragraph[0].name);
}

fn read_json_typed(raw_json: &str) -> Article {
    let parsed: Article = serde_json::from_str(raw_json).unwrap();
    return parsed
    
}

和第一个例子有三处不同:第一,是我们定义两个 的序列号/反序列化的结构;然后我读取 JSON 数据结构指定  对象作为类型;第三,我们读取解析结构使用的不是 Emun方式,而是  :  。

serde
Article
struct
parsed.paragraph[0].name

现在我们可以指定具体的类型和名称读JSON 内容。

但如果我们提供的 JSON 数据和结构不匹配的话:

{
  "article": "how to work with json in Rust",
  "author": "tdep",
  "paragraph": [
    {
      "name": 1
    },
    {
      "name": "strongly typed"
    },
    {
      "name": "writing json"
    }
  ]
}

我们把 JSON 中的第一个  字段改成数字,程序会出错:

name
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Error("invalid type: integer `1`, expected a string", line: 8, column: 15)', src/main.rs:44:58

或者我们把 key 改成  :

“article”
“name”
{
  "name": "how to work with json in Rust",
  "author": "tdep",
  "paragraph": [
    {
      "name": "untyped"
    },
    {
      "name": "strongly typed"
    },
    {
      "name": "writing json"
    }
  ]
}

程序也会出错:

thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Error("missing field `article`", line: 17, column: 1)', src/main.rs:44:58

因为,Rust 无法检测 JSON 中的  字段。

article

这是一种更好的接收 JSON 数据的办法。

接下来让我们看下如何反过来操作:从 Rust 数据结构到 JSON 字符串。

写JSON

我们将使用  函数将数据结构转换为 JSON 字符串,并使用 serde 的 使结构能够被序列化。 让我们看一个例子:

serde_json::to_string()
Serialize
use serde::{Deserialize, Serialize};

#[derive(Serialize, Deserialize)]
struct Paragraph {
    name: String
}

#[derive(Serialize, Deserialize)]
struct Article {
    article: String,
    author: String,
    paragraph: Vec<Paragraph>
}

fn main() {
    let article: Article = Article {
     article: String::from("how to work with json in Rust"),
     author: String::from("tdep"),
     paragraph: vec![
       Paragraph {
        name: String::from("untyped")
       },
       Paragraph {
        name: String::from("strongly typed")
       },
       Paragraph {
        name: String::from("writing json")
       }
     ]
    };

    let json = serde_json::to_string(&article).unwrap();

    println!("the JSON is: {}", json)
}

我们构建 ,然后将其引用传递给  函数。 运行 cargo 项目的结果:

Article
serde_json::to_string()
the JSON is: {"article":"how to work with json in Rust","author":"tdep","paragraph":[{"name":"untyped"},{"name":"strongly typed"},{"name":"writing json"}]}

我们已经了解了如何在 Rust 中以快速、安全和高效的方式处理 JSON。 还值得一提的是,我们使用  或  完成的每个操作,也可以使用 ,  不同的是: 序列化 (或反序列化)到一个vector,以及 到任何可写的输出(例如一个文件)。

serde_json::from_string
serde_json::to_string
serde_json::to_vec
serde_json::to_writer
to_vec
to_writer