最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Rust 中解析 JSON的方法

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

Rust 中如何解析 JSON

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

JSON 解析基礎(chǔ)知識(shí)

手動(dòng)解析 JSON

要開(kāi)始在 Rust 中使用 JSON,您需要安裝一個(gè)可以輕松操作 JSON 的庫(kù)。目前可用的流行crate之一是 serde-json 。您可以通過(guò)運(yùn)行以下命令來(lái)安裝它:

cargo add serde-json

完成后,您可以像這樣手動(dòng)創(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(())
}

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

使用 Serde 解析 JSON

Serde 是一個(gè)crate,可以幫助您將數(shù)據(jù)序列化和反序列化為各種格式,其中一個(gè)流行的用途是用于 JSON。如果您使用 Rust 編寫(xiě) Web 服務(wù),Serde 是您的朋友,因?yàn)槟鷮⒔?jīng)常處理可能需要發(fā)送或接收的 JSON 數(shù)據(jù)。 Serde 提供了兩個(gè)主要traits來(lái)幫助您實(shí)現(xiàn)此目的: SerializeDeserialize 。為了方便起見(jiàn),添加了派生宏實(shí)現(xiàn)來(lái)幫助解決此問(wèn)題。請(qǐng)參閱下文了解如何執(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();
}

您還可以通過(guò)添加實(shí)現(xiàn) SerializeDeserialize 的結(jié)構(gòu)作為另一個(gè)也實(shí)現(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 服務(wù)中。例如,當(dāng)您收到對(duì)具有 JSON 正文的 API 的 POST 請(qǐng)求時(shí),您通常會(huì)將相關(guān)的 Json 類(lèi)型作為處理函數(shù)參數(shù)傳遞。見(jiàn)下文:

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 字符串轉(zhuǎn)換為結(jié)構(gòu)體的代碼片段之外,您還可以從其字節(jié)表示形式轉(zhuǎn)換為結(jié)構(gòu)體:

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

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

同樣,您也可以使用 .from_reader() 方法從 JSON IO 流讀取 JSON 并將其轉(zhuǎn)換為結(jié)構(gòu)體。以下是取自 serde_json 文檔的示例,說(shuō)明如何將其與 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()));
    }
}

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

Comparing Rust JSON crates

比較 Rust JSON crates

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

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

serde-json

serde-json 是最容易使用的 Rust JSON 庫(kù)。它不需要額外的依賴(lài)項(xiàng)來(lái)使用,并且當(dāng)您需要訪(fǎng)問(wèn)原始 JSON 值的慣用操作時(shí),通常建議與 serde 一起使用。 serde-json 還支持 no_std ,允許您關(guān)閉默認(rèn)的 std 功能并啟用 alloc 。

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

simd-json

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

文檔中提到 simd-json 可以在本機(jī)目標(biāo)編譯上滿(mǎn)負(fù)荷使用。您可以通過(guò)在運(yùn)行程序時(shí)啟用 rustc 中的以下編譯器選項(xiàng)來(lái)做到這一點(diǎn),如下所示:

rustc -C target-cpu=native

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

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

一般來(lái)說(shuō),雖然這個(gè)庫(kù)相當(dāng)快,但應(yīng)該注意的是,由于它是 C++ 的 rust 語(yǔ)言綁定,因此該 crate 中存在相當(dāng)多的不安全代碼。這并不是說(shuō)你不應(yīng)該使用它,而是要謹(jǐn)慎使用它(正如crate所說(shuō))。盡管如此,有一個(gè)關(guān)于安全的部分詳細(xì)介紹了如何堅(jiān)持最佳實(shí)踐(如單元測(cè)試)以確保crates盡可能安全地使用。

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

一般來(lái)說(shuō), simd-json 的 API 與 serde-json 相同,因此如果您想隨時(shí)切換,那么通常這樣做不會(huì)有任何問(wèn)題。

sonic-rs

sonic-rs 是具有 SIMD 功能的 JSON 操作的 Rust 實(shí)現(xiàn)。該庫(kù)還有 C++ 和 Go 中的對(duì)應(yīng)庫(kù)!雖然它過(guò)去需要 Rust nightly 工具鏈,但它支持穩(wěn)定的 Rust。與 simd-json 類(lèi)似,它也需要 x86 CPU 架構(gòu)才能滿(mǎn)負(fù)荷運(yùn)行。

simd-json 一樣,要使用 sonic-rs 您需要在運(yùn)行程序時(shí)在 rustc 中啟用以下編譯器選項(xiàng):

rustc -C target-cpu=native

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

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

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

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

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

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

基準(zhǔn)

您可以在此處找到 simd-jsonserde-json 的基準(zhǔn)。 simd-jsonserde-json 相比有相當(dāng)顯著的改進(jìn)。

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

尾聲

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

原文地址:Parsing JSON in Rust

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

相關(guān)文章

  • rust?中生成與使用protobuf的方法

    rust?中生成與使用protobuf的方法

    這篇文章主要介紹了rust中protobuf生成與使用,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-05-05
  • Rust 累計(jì)時(shí)間長(zhǎng)度的操作方法

    Rust 累計(jì)時(shí)間長(zhǎng)度的操作方法

    在Rust中,如果你想要記錄累計(jì)時(shí)間,通??梢允褂脴?biāo)準(zhǔn)庫(kù)中的std::time::Duration類(lèi)型,這篇文章主要介紹了Rust如何累計(jì)時(shí)間長(zhǎng)度,需要的朋友可以參考下
    2024-05-05
  • Rust用宏實(shí)現(xiàn)參數(shù)可變的函數(shù)的實(shí)現(xiàn)示例

    Rust用宏實(shí)現(xiàn)參數(shù)可變的函數(shù)的實(shí)現(xiàn)示例

    本文主要介紹了Rust用宏實(shí)現(xiàn)參數(shù)可變的函數(shù)的實(shí)現(xiàn)示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2024-03-03
  • 在win10上使用mingw64編譯器配置Rust開(kāi)發(fā)環(huán)境和idea 配置Rust 插件

    在win10上使用mingw64編譯器配置Rust開(kāi)發(fā)環(huán)境和idea 配置Rust 插件

    在win10上配置 Rust 開(kāi)發(fā)環(huán)境(使用 mingw64編譯器)和 idea 配置 Rust 插件的相關(guān)知識(shí),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2023-03-03
  • Rust中的模塊系統(tǒng)之控制作用域與私有性詳解

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

    這篇文章總結(jié)了Rust模塊系統(tǒng)的基本規(guī)則,包括如何聲明模塊、路徑訪(fǎng)問(wèn)、私有性與公開(kāi)性,以及如何使用`use`關(guān)鍵字簡(jiǎn)化路徑引用,通過(guò)一個(gè)餐廳系統(tǒng)示例,展示了如何利用模塊劃分功能,并介紹了如何在其他模塊或二進(jìn)制crate中使用這些模塊
    2025-02-02
  • Rust裸指針的安全性實(shí)例講解

    Rust裸指針的安全性實(shí)例講解

    裸指針是一個(gè)不包含所有權(quán)和借用關(guān)系的原始指針,它們與常規(guī)指針相比沒(méi)有任何限制和保護(hù)措施,這篇文章主要介紹了Rust裸指針的安全性實(shí)例,需要的朋友可以參考下
    2023-05-05
  • Rust在寫(xiě)庫(kù)時(shí)實(shí)現(xiàn)緩存的操作方法

    Rust在寫(xiě)庫(kù)時(shí)實(shí)現(xiàn)緩存的操作方法

    Moka是一個(gè)用于Rust的高性能緩存庫(kù),它提供了多種類(lèi)型的緩存數(shù)據(jù)結(jié)構(gòu),包括哈希表、LRU(最近最少使用)緩存和?支持TTL(生存時(shí)間)緩存,這篇文章給大家介紹Rust在寫(xiě)庫(kù)時(shí)實(shí)現(xiàn)緩存的相關(guān)知識(shí),感興趣的朋友一起看看吧
    2024-01-01
  • 使用cargo install安裝Rust二進(jìn)制工具過(guò)程

    使用cargo install安裝Rust二進(jìn)制工具過(guò)程

    cargoinstall是一個(gè)用于安裝包含可執(zhí)行目標(biāo)的Rust包的命令行工具,類(lèi)似于系統(tǒng)軟件包管理器,但它為Rust開(kāi)發(fā)者提供了一種簡(jiǎn)潔的方式來(lái)安裝和管理命令行工具,安裝后,二進(jìn)制文件會(huì)存儲(chǔ)在$HOME/.cargo/bin目錄中,需要將該目錄添加到$PATH環(huán)境變量中才能在命令行中直接運(yùn)行
    2025-02-02
  • 關(guān)于使用rust調(diào)用c++靜態(tài)庫(kù)并編譯nodejs包的問(wèn)題

    關(guān)于使用rust調(diào)用c++靜態(tài)庫(kù)并編譯nodejs包的問(wèn)題

    這篇文章主要介紹了使用rust調(diào)用c++靜態(tài)庫(kù)并編譯nodejs包的問(wèn)題,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-08-08
  • 用rust?寫(xiě)一個(gè)jar包?class沖突檢測(cè)工具

    用rust?寫(xiě)一個(gè)jar包?class沖突檢測(cè)工具

    這篇文章主要介紹了用rust?寫(xiě)一個(gè)jar包?class沖突檢測(cè)工具?的相關(guān)資料,需要的朋友可以參考下
    2023-05-05

最新評(píng)論

高清| 凤翔县| 石家庄市| 满城县| 合阳县| 沧州市| 蚌埠市| 东莞市| 日土县| 定州市| 玉树县| 三江| 喀喇| 会宁县| 邵阳县| 江油市| 曲阳县| 苍溪县| 平谷区| 崇明县| 绥阳县| 射洪县| 故城县| 正蓝旗| 饶阳县| 嵊泗县| 黑河市| 陈巴尔虎旗| 佳木斯市| 大埔县| 桃源县| 通河县| 西乡县| 馆陶县| 宁强县| 诸城市| 娄烦县| 金川县| 三明市| 棋牌| 定远县|