0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

Prost的最佳實踐經(jīng)驗

科技綠洲 ? 來源:TinyZ ? 作者:TinyZ ? 2023-09-20 11:09 ? 次閱讀

Prost是一個用于序列化和反序列化協(xié)議緩沖區(qū)數(shù)據(jù)的Rust語言庫。它使用Google Protocol Buffers語言來定義協(xié)議,并生成Rust代碼以便使用該協(xié)議。 Prost具有高性能的特點,并且支持許多protobuf功能,例如嵌套消息、默認值、枚舉類型以及變長編碼。

Prost支持從protobuf2和protobuf3生成代碼,而且可以與其他Rust語言庫和框架無縫集成。

模塊場景和基礎(chǔ)用法

Prost可以用于許多場景,包括網(wǎng)絡(luò)通信、持久化、日志記錄等。在這里,我們將通過一個簡單的例子來介紹Prost的基礎(chǔ)用法。

首先在Cargo.toml中引入prost模塊,示例配置如下:

[dependencies]
prost = "0.11"
# Only necessary if using Protobuf well-known types:
prost-types = "0.11"

假設(shè)我們有一個動物園,里面有許多不同種類的動物。我們可以使用Prost來定義一個動物的協(xié)議,然后使用該協(xié)議來序列化和反序列化動物對象。

首先,我們需要定義動物的protobuf文件。在這里,我們定義了一個動物具有名稱、年齡和類型。動物類型是一個枚舉類型,它可以是狗、貓或鳥。

syntax = "proto3";

enum AnimalType {
    DOG = 0;
    CAT = 1;
    BIRD = 2;
}

message Animal {
    string name = 1;
    uint32 age = 2;
    AnimalType animal_type = 3;
}

接下來,我們需要使用Prost生成Rust代碼。我們可以使用以下命令來執(zhí)行此操作:

$ protoc --rust_out . animals.proto

這將生成一個名為animals.rs的文件,其中包含與protobuf定義相對應(yīng)的Rust代碼。

接下來,我們可以使用Prost來序列化和反序列化動物對象。以下是一個示例代碼:

use prost::{Enumeration, Message};

#[derive(Clone, PartialEq, Message)]
pub struct Animal {
    #[prost(string, tag="1")]
    pub name: String,
    #[prost(uint32, tag="2")]
    pub age: u32,
    #[prost(enumeration="AnimalType", tag="3")]
    pub animal_type: i32,
}

#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Enumeration)]
pub enum AnimalType {
    Dog = 0,
    Cat = 1,
    Bird = 2,
}

fn main() {
    let mut animal = Animal::default();
    animal.name = "Tom".to_string();
    animal.age = 3;
    animal.animal_type = AnimalType::Cat as i32;

    let mut buf = Vec::new();
    animal.encode(&mut buf).unwrap();

    let decoded_animal = Animal::decode(&buf[..]).unwrap();
    assert_eq!(animal, decoded_animal);
    println!("{:?}", animal);
}
//  輸出結(jié)果:
//  Animal { name: "Tom", age: 3, animal_type: Cat }

在這個示例代碼中,我們定義了一個名為Animal的結(jié)構(gòu)體,并使用prost宏將其與protobuf定義相關(guān)聯(lián)。我們還定義了一個名為AnimalType的枚舉類型,它與protobuf定義中的枚舉類型相對應(yīng)。

main函數(shù)中,我們創(chuàng)建了一個Animal對象,并將其序列化為字節(jié)數(shù)組。然后,我們將字節(jié)數(shù)組反序列化為另一個Animal對象,并使用assert_eq宏比較這兩個對象是否相等。

高級特性

Prost提供了許多高級特性,例如自定義類型、擴展字段、oneof等。在這里,我們將介紹其中一些特性。

自定義類型

有時,我們可能需要在protobuf定義中使用自定義類型。例如,我們可能需要使用自定義類型來表示日期或時間。在這種情況下,我們可以使用prost宏的bytes屬性來定義自定義類型。

以下是一個示例代碼:

syntax = "proto3";

message Date {
    bytes value = 1 [(prost(bytes_type) = "chrono::NaiveDate")];
}

message Time {
    bytes value = 1 [(prost(bytes_type) = "chrono::NaiveTime")];
}

在這個示例代碼中,我們定義了兩個消息類型:DateTime。它們都包含一個名為value的字節(jié)數(shù)組字段,并使用prost宏的bytes_type屬性將其與chrono庫中的NaiveDateNaiveTime類型相關(guān)聯(lián)。

自定義編解碼

Prost支持自定義編解碼,可以使用prost::Message trait來實現(xiàn)自定義編解碼。

impl Animal {
    pub fn from_bytes(bytes: &[u8]) - > Result< Self, prost::DecodeError > {
        Animal::decode(bytes)
    }

    pub fn to_bytes(&self) - > Result< Vec< u8 >, prost::EncodeError > {
        let mut buf = Vec::new();
        self.encode(&mut buf)?;
        Ok(buf)
    }
}
fn main() {
    let mut animal = Animal::default();
    animal.name = "Tom".to_string();
    animal.age = 3;
    animal.animal_type = AnimalType::Cat as i32;

    let bytes = animal.to_bytes();
    println!("{:?}", Animal::from_bytes(&bytes.unwrap()));
}
//  輸出結(jié)果:
// Ok(Animal { name: "Tom", age: 3, animal_type: Cat })

擴展字段

有時,我們可能需要向protobuf消息添加額外的字段,但是又不想破壞現(xiàn)有的消息格式。在這種情況下,我們可以使用擴展字段。

擴展字段是在protobuf定義中定義的,但是在生成的Rust代碼中不會出現(xiàn)。它們可以用來存儲任何類型的數(shù)據(jù),并且可以與protobuf消息一起序列化和反序列化。

以下是一個示例代碼:

syntax = "proto3";

message Animal {
    string name = 1;
    uint32 age = 2;
    AnimalType animal_type = 3;

    map< string, bytes > extensions = 1000;
}

在這個示例代碼中,我們添加了一個名為extensions的字段,它是一個map類型,可以存儲任何類型的數(shù)據(jù)。此字段的標簽為1000,這意味著它是一個擴展字段。

在Rust代碼中,我們可以使用prost::Message trait的extensions方法來訪問擴展字段。以下是一個示例代碼:

use prost::{Enumeration, Message};
use std::collections::HashMap;

#[derive(Clone, PartialEq, Message)]
pub struct Animal {
    #[prost(string, tag="1")]
    pub name: String,
    #[prost(uint32, tag="2")]
    pub age: u32,
    #[prost(enumeration="AnimalType", tag="3")]
    pub animal_type: i32,
    #[prost(map="string, bytes", tag="1000")]
    pub extensions: HashMap< String, Vec< u8 >>,
}

#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Enumeration)]
pub enum AnimalType {
    Dog = 0,
    Cat = 1,
    Bird = 2,
}

fn main() {
    let mut animal = Animal::default();
    animal.extensions.insert("color".to_string(), b"brown".to_vec());
    
    let mut buf = Vec::new();
    animal.encode(&mut buf).unwrap();
    
    let decoded_animal = Animal::decode(&buf[..]).unwrap();
    assert_eq!(animal.extensions, decoded_animal.extensions);
}

在這個示例代碼中,我們創(chuàng)建了一個Animal對象,并向其添加了一個名為color的擴展字段。然后,我們將該對象序列化為字節(jié)數(shù)組,并將其反序列化為另一個Animal對象。最后,我們使用assert_eq宏比較這兩個對象的擴展字段是否相等。

Proto Oneof

有時,我們可能需要在protobuf消息中使用oneof語法,以表示字段中的多個可能類型。在這種情況下,我們可以使用prost宏的oneof屬性來定義oneof字段。

以下是一個示例代碼:

syntax = "proto3";

message Animal {
    string name = 1;
    uint32 age = 2;
    oneof animal_type {
        Dog dog = 3;
        Cat cat = 4;
        Bird bird = 5;
    }
}
message Dog {
    string breed = 1;
}
message Cat {
    bool has_tail = 1;
}
message Bird {
    uint32 wingspan = 1;
}

在這個示例代碼中,我們定義了一個名為Animal的消息類型,它包含一個名為animal_typeoneof字段。oneof字段中包含三個可能的類型:DogCatBird。每個類型都包含與其相關(guān)聯(lián)的字段。

在Rust代碼中,我們可以使用prost::Oneof trait來訪問oneof字段。以下是一個示例代碼:

use prost::{Enumeration, Message, Oneof};
use std::collections::HashMap;
use core::option::Option;

#[derive(Clone, PartialEq, Message)]
pub struct Animal {
    #[prost(string, tag="1")]
    pub name: String,
    #[prost(uint32, tag="2")]
    pub age: u32,
    #[prost(oneof="AnimalType", tag="3,4,5")]
    pub animal_type: Option< AnimalType >,
}
#[derive(Clone, Debug, PartialEq, Enumeration)]
pub enum AnimalType {
    #[prost(message, tag = "3", name = "Dog")]
    Dog(Dog),
    #[prost(message, tag = "4", name = "Cat")]
    Cat(Cat),
    #[prost(message, tag = "5", name = "Bird")]
    Bird(Bird),
}
#[derive(Clone, PartialEq, Message)]
pub struct Dog {
    #[prost(string, tag="1")]
    pub breed: String
}
#[derive(Clone, PartialEq, Message)]
pub struct Cat {
    #[prost(bool, tag="1")]
    pub has_tail: bool
}
#[derive(Clone, PartialEq, Message)]
pub struct Bird {
    #[prost(uint32, tag="1")]
    pub wingspan: u32
}
fn main() {
    let mut animal = Animal::default();
    animal.name = "Tom".to_string();
    animal.age = 3;
    animal.animal_type = Some(AnimalType::Cat(Cat { has_tail: true }));
    
    let mut buf = Vec::new();
    animal.encode(&mut buf).unwrap();
    
    let decoded_animal = Animal::decode(&buf[..]).unwrap();
    assert_eq!(animal, decoded_animal);
}

在這個示例代碼中,我們創(chuàng)建了一個Animal對象,并將其cat字段設(shè)置為一個包含has_tail字段的Cat對象。然后,我們將該對象序列化為字節(jié)數(shù)組,并將其反序列化為另一個Animal對象。最后,我們使用assert_eq宏比較這兩個對象是否相等。

prost最佳實踐

以下是一些使用Prost的最佳實踐經(jīng)驗:

  • ? 在protobuf定義中使用簡單的數(shù)據(jù)類型。Prost支持許多protobuf功能,例如嵌套消息、默認值、枚舉類型以及變長編碼。但是,使用這些功能可能會導(dǎo)致生成的Rust代碼變得復(fù)雜。因此,為了使代碼保持簡單和易于維護,請盡可能使用簡單的數(shù)據(jù)類型。
  • ? 在Rust代碼中使用結(jié)構(gòu)體。Prost生成的Rust代碼可以是一個模塊或一個trait。但是,使用結(jié)構(gòu)體可以使代碼更易于使用和維護。因此,建議在Rust代碼中使用結(jié)構(gòu)體。
  • ? 使用自定義類型時,請使用標準庫或第三方庫。Prost支持許多自定義類型,包括日期、時間、UUID等。但是,使用標準庫或第三方庫可能會使代碼更加通用和可移植。因此,建議在使用自定義類型時使用標準庫或第三方庫。
  • ? 在使用擴展字段時,請注意字段標簽。擴展字段的標簽必須大于1000。因此,請確保您為擴展字段選擇一個大于1000的標簽。
  • ? 在使用oneof語法時,請選擇一個好的字段名稱。oneof字段包含多個可能的類型,因此請為其選擇一個好的字段名稱。這將使代碼更易于理解和維護。

總結(jié)

Prost是一個高性能的Rust語言庫,可用于序列化和反序列化協(xié)議緩沖區(qū)數(shù)據(jù)。它支持許多protobuf功能,并且可以與其他Rust語言庫和框架無縫集成。在本教程中,我們介紹了Prost的基礎(chǔ)用法和一些高級特性,并提供了一些最佳實踐經(jīng)驗。我們希望這個教程能夠幫助您更好地使用Prost。

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學習之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 編碼
    +關(guān)注

    關(guān)注

    6

    文章

    942

    瀏覽量

    54836
  • 代碼
    +關(guān)注

    關(guān)注

    30

    文章

    4788

    瀏覽量

    68625
  • rust語言
    +關(guān)注

    關(guān)注

    0

    文章

    57

    瀏覽量

    3009
收藏 人收藏

    評論

    相關(guān)推薦

    嵌入式系統(tǒng)開發(fā)實踐經(jīng)驗分享

    工程師一刻也沒忘記交付能同時滿足質(zhì)量、時間安排和預(yù)算目標的項目的需求。一個事半功倍的方法 就是借鑒嵌入式系統(tǒng)開發(fā)人員社區(qū)多年來累計的經(jīng)驗教訓。下面我們就來了解一些為嵌入式開發(fā)帶來了最佳實踐的重要
    發(fā)表于 12-14 11:39 ?2448次閱讀
    嵌入式系統(tǒng)開發(fā)<b class='flag-5'>實踐經(jīng)驗</b>分享

    有誰能多介紹些AD的實踐經(jīng)驗嗎?

    有誰能多介紹些AD的實踐經(jīng)驗嗎?
    發(fā)表于 04-03 09:20

    實踐經(jīng)驗還是理論學習

    2014考研已結(jié)束,2015考研又開始準備了,作為一個動手能力平平理論水平也不高的電子一族是走考研理論學習之路還是走工作實踐經(jīng)驗之路?大家有什么樣的看法???......
    發(fā)表于 03-10 17:24

    請問有關(guān)于STM32普通IO口模擬操作SMBus通信的相關(guān)實踐經(jīng)驗嗎?

    求助啊,哪位有關(guān)于STM32普通IO口模擬操作SMBus通信的相關(guān)實踐經(jīng)驗?分享下,多謝。普通IO口模擬操作I2C的例子很多,也比較容易,SMBus與I2C有很多類似的地方,應(yīng)該可以通用,但是很少看到有這方的相關(guān)詳細介紹。
    發(fā)表于 10-22 08:43

    Dockerfile的最佳實踐

    ”微服務(wù)一條龍“最佳指南-“最佳實踐”篇:Dockerfile
    發(fā)表于 07-11 16:22

    工業(yè)吸塵吸水機谷歌優(yōu)化推廣,12年實踐經(jīng)驗

    `工業(yè)吸塵器的外貿(mào)怎么推廣,網(wǎng)站優(yōu)化更有效果工業(yè)吸塵吸水機谷歌優(yōu)化推廣,12年實踐經(jīng)驗掃地機關(guān)鍵詞如何SEO優(yōu)化到GOOGLE首頁 曾經(jīng)我以為GOOGLE SEO優(yōu)化更適合機械制造商,A但現(xiàn)在我
    發(fā)表于 10-28 15:53

    編譯器原理及實踐

    具體介紹編譯軟件的原理及相關(guān)的實踐經(jīng)驗,是編程學習的相關(guān)的資料。
    發(fā)表于 01-12 11:35 ?0次下載

    不同行業(yè)客戶如何利用物聯(lián)網(wǎng)平臺的實踐經(jīng)驗案例分析

    物聯(lián)網(wǎng)是IT和OT結(jié)合的產(chǎn)物,任何以IT為中心的定義都無法描述OT的重要性,反之亦然。在本文中我將不同行業(yè)客戶如何利用物聯(lián)網(wǎng)平臺的實踐經(jīng)驗分享給大家。
    的頭像 發(fā)表于 12-01 16:46 ?5363次閱讀

    福田汽車對工業(yè)互聯(lián)網(wǎng)的探索及實踐經(jīng)驗

    在2020工業(yè)互聯(lián)網(wǎng)大會工業(yè)互聯(lián)網(wǎng)5G與工業(yè)互聯(lián)網(wǎng)融合發(fā)展主論壇上,北汽福田汽車集團副總經(jīng)理楊國濤發(fā)表題為《工業(yè)互聯(lián)網(wǎng)賦能商用車第一品牌》的演講,分享福田汽車對工業(yè)互聯(lián)網(wǎng)的探索及實踐經(jīng)驗。 專家說
    的頭像 發(fā)表于 10-22 15:33 ?3784次閱讀

    在汽車行業(yè)多年來戰(zhàn)略與設(shè)計上的理論與實踐經(jīng)驗

    istd汽車咨詢團隊,以及旗下戰(zhàn)略管理咨詢團隊思略特與數(shù)字化體驗中心,結(jié)合在汽車行業(yè)多年來戰(zhàn)略與設(shè)計上的理論與實踐經(jīng)驗,嘗試為車企解惑產(chǎn)品體驗迷思、甄別創(chuàng)新方向、定位關(guān)鍵戰(zhàn)局并把握先機,找到真正實現(xiàn)差異化競爭的核心要素。
    的頭像 發(fā)表于 11-17 14:59 ?3570次閱讀

    OpenHarmony Tech Day技術(shù)日 創(chuàng)新教育教學實踐經(jīng)驗分享

      張澤華就基于OpenHarmony的創(chuàng)新教育教學實踐經(jīng)驗分享進行演講
    的頭像 發(fā)表于 04-25 14:44 ?761次閱讀
    OpenHarmony Tech Day技術(shù)日 創(chuàng)新教育教學<b class='flag-5'>實踐經(jīng)驗</b>分享

    Modbus協(xié)議通訊學習仿真器虛擬串口完整套裝實踐經(jīng)驗總結(jié)

    Modbus通訊學習完整套裝,實踐經(jīng)驗總結(jié)親測好用助力新手快速掌握MOSBUS協(xié)議的讀寫操作,非常好用。工具套裝包括MODBUS仿真器、虛擬串口對、MODBUS調(diào)試助手、串口調(diào)試助手。提供操作教程。
    的頭像 發(fā)表于 11-22 14:49 ?1096次閱讀
    Modbus協(xié)議通訊學習仿真器虛擬串口完整套裝<b class='flag-5'>實踐經(jīng)驗</b>總結(jié)

    使用Koordinator支持異構(gòu)資源管理和任務(wù)調(diào)度場景的實踐經(jīng)驗

    Koordinator 是阿里云基于過去我們建設(shè)的統(tǒng)一調(diào)度系統(tǒng)中積累的技術(shù)和實踐經(jīng)驗,對外開源了新一代的調(diào)度系統(tǒng)。
    的頭像 發(fā)表于 08-15 10:09 ?747次閱讀
    使用Koordinator支持異構(gòu)資源管理和任務(wù)調(diào)度場景的<b class='flag-5'>實踐經(jīng)驗</b>

    訊維集中電源控制器:案例研究與實踐經(jīng)驗分享

    集中電源控制器在實踐中的應(yīng)用非常廣泛,以下是一些案例研究與實踐經(jīng)驗分享: 數(shù)據(jù)中心應(yīng)用案例:在數(shù)據(jù)中心中,集中電源控制器可以實現(xiàn)對服務(wù)器、網(wǎng)絡(luò)設(shè)備和存儲設(shè)備等關(guān)鍵基礎(chǔ)設(shè)施的電源集中管理和監(jiān)控。通過
    的頭像 發(fā)表于 01-30 14:59 ?560次閱讀
    訊維集中電源控制器:案例研究與<b class='flag-5'>實踐經(jīng)驗</b>分享

    中科曙光憑借技術(shù)優(yōu)勢以及實踐經(jīng)驗獲頒“核心參編單位”證書

    近日,中國人工智能產(chǎn)業(yè)發(fā)展聯(lián)盟面向參編單位頒發(fā)證書。中科曙光憑借技術(shù)優(yōu)勢以及實踐經(jīng)驗,全程參編《面向訓練任務(wù)的人工智能通用技術(shù)要求》標準(以下簡稱“標準”),獲頒“核心參編單位”證書。
    的頭像 發(fā)表于 03-25 11:05 ?633次閱讀