欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Rust 中解析 JSON的方法

 更新時間:2024年03月06日 10:09:29   作者:xuejianxinokok  
要開始在 Rust 中使用 JSON,您需要安裝一個可以輕松操作 JSON 的庫,目前可用的流行crate之一是 serde-json,在本文中,我們將討論如何在 Rust 中使用 JSON 解析庫,以及比較最流行的庫及其性能

Rust 中如何解析 JSON

在本文中,我們將討論如何在 Rust 中使用 JSON 解析庫,以及比較最流行的庫及其性能。

JSON 解析基礎知識

手動解析 JSON

要開始在 Rust 中使用 JSON,您需要安裝一個可以輕松操作 JSON 的庫。目前可用的流行crate之一是 serde-json 。您可以通過運行以下命令來安裝它:

cargo add serde-json

完成后,您可以像這樣手動創(chuàng)建 JSON:

use serde_json::{Result, Value};
fn untyped_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 serde_json::Value.
    let v: Value = serde_json::from_str(data)?;
    // Access parts of the data by indexing with square brackets.
    println!("Please call {} at the number {}", v["name"], v["phones"][0]);
    Ok(())
}

然而,我們可以做得更好。例如,可以將結構 序列化為 JSON 與 或反序列化,這很常用。我們可以在 JSON 模板、Web 服務、CLI 參數(shù)等中使用它。在下一節(jié)中完成這一點。

使用 Serde 解析 JSON

Serde 是一個crate,可以幫助您將數(shù)據(jù)序列化和反序列化為各種格式,其中一個流行的用途是用于 JSON。如果您使用 Rust 編寫 Web 服務,Serde 是您的朋友,因為您將經(jīng)常處理可能需要發(fā)送或接收的 JSON 數(shù)據(jù)。 Serde 提供了兩個主要traits來幫助您實現(xiàn)此目的: SerializeDeserialize 。為了方便起見,添加了派生宏實現(xiàn)來幫助解決此問題。請參閱下文了解如何執(zhí)行此操作:

use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize)]
pub struct MyStruct {
    message: String
}
fn convert_json_to_struct() {
    // create a raw JSON string from the json! macro and turn it into a MyStruct struct
    let raw_json_string = json!({"message": "Hello world!"});
    let my_struct: MyStruct = serde_json::from_str(raw_json_string).unwrap();
}

您還可以通過添加實現(xiàn) SerializeDeserialize 的結構作為另一個也實現(xiàn) SerializeDeserialize

use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize)]
pub struct Post {
      nested_json: PostMetadata,
    title: String,
      body: String
}
#[derive(Serialize, Deserialize)]
pub struct PostMetadata {
      timestamp_created: DateTime<Utc>,
    timestamp_last_updated: Datetime<Utc>,
      categories: Vec<String>,
}

一種用例是將 JSON 嵌套在 Web 服務中。例如,當您收到對具有 JSON 正文的 API 的 POST 請求時,您通常會將相關的 Json 類型作為處理函數(shù)參數(shù)傳遞。見下文:

use axum::Json;
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize)]
pub struct Post {
      nested_json: PostMetadata,
    title: String,
      body: String
}
#[derive(Serialize, Deserialize)]
pub struct PostMetadata {
      timestamp_created: DateTime<Utc>,
    timestamp_last_updated: Datetime<Utc>,
      categories: Vec<String>,
}
async fn receive_some_json(
  // this extractor consumes a JSON body and converts it into the struct type given
    Json(json): Json<Post>
) -> Json<Post> {
  println!("{:?}", json);
    Json(json)
}

除了前面顯示如何使用 serde_json 從 JSON 字符串轉換為結構體的代碼片段之外,您還可以從其字節(jié)表示形式轉換為結構體:

let json_as_bytes = b" {   \"message\": \"Hello world!\",    }";
    let my_struct: MyStruct = serde_json::from_slice(json_as_bytes).unwrap();

如果您想將結構作為字節(jié)數(shù)組存儲在某處,然后稍后將其轉回結構,那么這特別有用!

同樣,您也可以使用 .from_reader() 方法從 JSON IO 流讀取 JSON 并將其轉換為結構體。以下是取自 serde_json 文檔的示例,說明如何將其與 TCP 流一起使用:

use serde::Deserialize;
use std::error::Error;
use std::net::{TcpListener, TcpStream};
#[derive(Deserialize, Debug)]
struct User {
    fingerprint: String,
    location: String,
}
fn read_user_from_stream(tcp_stream: TcpStream) -> Result<User, Box<dyn Error>> {
    let mut to_be_deserialized = serde_json::Deserializer::from_reader(tcp_stream);
    let user = User::deserialize(&mut to_be_deserialized)?;
    Ok(user)
}
fn main() {
    let listener = TcpListener::bind("127.0.0.1:4000").unwrap();
    for stream in listener.incoming() {
        println!("{:#?}", read_user_from_stream(stream.unwrap()));
    }
}

通過這種方式,您可以直接從流中反序列化,而不是在內(nèi)存中添加緩沖。如果您收到大量基于 JSON 的數(shù)據(jù),這可以為您提供很大幫助!

Comparing Rust JSON crates

比較 Rust JSON crates

盡管 serde-json 可能是最受歡迎的 crate,但它絕不是最快的。與此同時,還出現(xiàn)了一些其他 crate,以提高一般 JSON 解析性能。然而,為了換取性能,CPU SIMD 擴展要求存在一些注意事項。不安全代碼的使用也有所增加,盡管一般來說,我們已盡最大努力確保代碼可以安全使用。

所有這些 crate 大部分都具有相同的 API。除非另有說明,否則您可以安全地在這些庫之間切換,并期望每個庫中使用大致相同的 JSON 接口。

serde-json

serde-json 是最容易使用的 Rust JSON 庫。它不需要額外的依賴項來使用,并且當您需要訪問原始 JSON 值的慣用操作時,通常建議與 serde 一起使用。 serde-json 還支持 no_std ,允許您關閉默認的 std 功能并啟用 alloc 。

就性能而言, serde-json 本身無論如何都不慢。但是,它比此列表中的其他一些 JSON 庫慢。這主要是由于針對 非并行 CPU 使用進行了優(yōu)化。特別是如果您能夠訪問現(xiàn)代 x86 CPU,您可能需要繼續(xù)閱讀以了解有關一些性能更好的選項的更多信息。然而,這個crate 也是 Rust 社區(qū)中使用最廣泛和支持最多的,所以如果您遇到問題,那么很容易找到幫助!

simd-json

simd-jsonsimdjson C++ JSON 解析器的 Rust 語言綁定,內(nèi)置了 serde 兼容性。顧名思義,該庫使用 SIMD(單指令的縮寫)多個數(shù)據(jù)。這是一種能夠通過并行處理來處理多個數(shù)據(jù)點的技術,使其速度顯著加快!但需要注意的是,它要求您的系統(tǒng)支持 x86,并且在運行時它將選擇最佳的 SIMD 功能集以實現(xiàn)性能。如果沒有可用的功能集,還有一個未優(yōu)化的 Rust 實現(xiàn),但在文檔中提到不應依賴它。

文檔中提到 simd-json 可以在本機目標編譯上滿負荷使用。您可以通過在運行程序時啟用 rustc 中的以下編譯器選項來做到這一點,如下所示:

rustc -C target-cpu=native

但是,如果您像大多數(shù)使用 Cargo 的人一樣,您可能想使用 cargo run 。如示例中所示,您可以在 .cargo/config 處創(chuàng)建配置,然后添加以下內(nèi)容:

[build]
rustflags = ["-C", "target-cpu=native"]

一般來說,雖然這個庫相當快,但應該注意的是,由于它是 C++ 的 rust 語言綁定,因此該 crate 中存在相當多的不安全代碼。這并不是說你不應該使用它,而是要謹慎使用它(正如crate所說)。盡管如此,有一個關于安全的部分詳細介紹了如何堅持最佳實踐(如單元測試)以確保crates盡可能安全地使用。

還應該提到的是,為了獲得最佳性能,通常最好啟用 jemallocmimalloc 功能,以便能夠充分利用該庫。

一般來說, simd-json 的 API 與 serde-json 相同,因此如果您想隨時切換,那么通常這樣做不會有任何問題。

sonic-rs

sonic-rs 是具有 SIMD 功能的 JSON 操作的 Rust 實現(xiàn)。該庫還有 C++ 和 Go 中的對應庫!雖然它過去需要 Rust nightly 工具鏈,但它支持穩(wěn)定的 Rust。與 simd-json 類似,它也需要 x86 CPU 架構才能滿負荷運行。

simd-json 一樣,要使用 sonic-rs 您需要在運行程序時在 rustc 中啟用以下編譯器選項:

rustc -C target-cpu=native

您可以在 .cargo/config 創(chuàng)建配置,然后添加以下內(nèi)容以在使用 cargo run 時啟用它:

[build]
rustflags = ["-C", "target-cpu=native"]

這使您無需執(zhí)行任何其他操作即可構建 SIMD!

simd-json 一樣,使用了相當數(shù)量的 unsafe 代碼。但是,如果您在庫中搜索不安全代碼,您可能會發(fā)現(xiàn)比以前的庫中更多的 unsafe 代碼。關于如何維護不安全保證的文檔也很少,因此盡管這個庫可能比 simd-json 更快,但您需要仔細檢查是否存在未定義的行為!

sonic-rs 另外還有一些額外的方法用于惰性評估和額外的速度。例如,如果您想要 JSON 字符串文字,則可以在反序列化時使用 LazyValue 類型將其轉換為仍包含正斜杠的 JSON 字符串值。如果您不怕不安全行為或者確定它不會出錯,還有很多 unchecked 方法可以使用。

雖然 sonic-rs 是一個相當快的庫,但它也是一個更新的 crate,因此 crate 中缺少一些方法,例如 from_reader (允許從 IO 流讀?。?。這已經(jīng)作為 GitHub 問題提出,所以希望它能盡快實施。

基準

您可以在此處找到 simd-jsonserde-json 的基準。 simd-jsonserde-json 相比有相當顯著的改進。

您可以在此處找到 sonic-rs 的基準,其中還將其與 simd-jsonserde-json 進行比較。正如您所看到的,最終結果的格式與 simd-jsonserde-json 基準測試的格式不同,因此每秒處理的數(shù)據(jù)量更難以理解。然而,在大多數(shù)情況下, sonic-rs 明顯(有時是巨大!)比 simd-jsonserde-json 快。

尾聲

謝謝閱讀!我希望本文能夠幫助您了解如何有效使用 Rust JSON 解析庫。

原文地址:Parsing JSON in Rust

到此這篇關于Rust 中如何解析 JSON?的文章就介紹到這了,更多相關Rust 解析 JSON內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • Rust 語言中的dyn 關鍵字及用途解析

    Rust 語言中的dyn 關鍵字及用途解析

    在Rust中,"dyn"關鍵字用于表示動態(tài)分發(fā)(dynamic dispatch),它通常與trait對象一起使用,以實現(xiàn)運行時多態(tài), 在Rust中,多態(tài)是通過trait和impl來實現(xiàn)的,這篇文章主要介紹了Rust 語言中的 dyn 關鍵字,需要的朋友可以參考下
    2024-03-03
  • Rust中的不安全代碼詳解

    Rust中的不安全代碼詳解

    這篇文章主要為大家介紹了Rust中的不安全代碼詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-04-04
  • Rust?語言println!?宏的格式占位符詳解

    Rust?語言println!?宏的格式占位符詳解

    這篇文章主要介紹了Rust語言的println!宏的格式占位符,這只是格式說明符的一部分清單,Rust?的格式化系統(tǒng)非常靈活和強大,支持更多的選項和組合,需要的朋友可以參考下
    2024-03-03
  • rust生命周期詳解

    rust生命周期詳解

    生命周期是rust中用來規(guī)定引用的有效作用域,在大多數(shù)時候,無需手動聲明,因為編譯器能夠自動推導,這篇文章主要介紹了rust生命周期相關知識,需要的朋友可以參考下
    2023-03-03
  • 利用rust實現(xiàn)一個命令行工具

    利用rust實現(xiàn)一個命令行工具

    這篇文章主要為大家詳細介紹了如何使用?Rust?和?clap?4.4.0?創(chuàng)建一個命令行工具?my_dev_tool,文中的示例代碼講解詳細,需要的小伙伴可以參考下
    2023-12-12
  • 深入了解Rust中引用與借用的用法

    深入了解Rust中引用與借用的用法

    這篇文章主要為大家詳細介紹了Rust語言中引用與借用的使用,文中的示例代碼講解詳細,具有一定的借鑒價值,需要的小伙伴可以了解一下
    2022-11-11
  • Rust如何使用config配置API

    Rust如何使用config配置API

    這篇文章主要介紹了Rust如何使用config配置API,這里記錄了如何聲明配置類型,讀取配置,通過環(huán)境變量來覆蓋配置值等開發(fā)中常見的動作,需要的朋友可以參考下
    2023-11-11
  • Rust中的模塊系統(tǒng)之控制作用域與私有性詳解

    Rust中的模塊系統(tǒng)之控制作用域與私有性詳解

    這篇文章總結了Rust模塊系統(tǒng)的基本規(guī)則,包括如何聲明模塊、路徑訪問、私有性與公開性,以及如何使用`use`關鍵字簡化路徑引用,通過一個餐廳系統(tǒng)示例,展示了如何利用模塊劃分功能,并介紹了如何在其他模塊或二進制crate中使用這些模塊
    2025-02-02
  • Rust生命周期之驗證引用有效性與防止懸垂引用方式

    Rust生命周期之驗證引用有效性與防止懸垂引用方式

    本文介紹了Rust中生命周期注解的應用,包括防止懸垂引用、在函數(shù)中使用泛型生命周期、生命周期省略規(guī)則、在結構體中使用生命周期、靜態(tài)生命周期以及如何將生命周期與泛型和特質(zhì)約束結合,通過這些機制,Rust在編譯時就能捕獲內(nèi)存安全問題
    2025-02-02
  • C和Java沒那么香了,Serverless時代Rust即將稱王?

    C和Java沒那么香了,Serverless時代Rust即將稱王?

    Serverless Computing,即”無服務器計算”,其實這一概念在剛剛提出的時候并沒有獲得太多的關注,直到2014年AWS Lambda這一里程碑式的產(chǎn)品出現(xiàn)。Serverless算是正式走進了云計算的舞臺
    2021-06-06

最新評論