精品国产人成在线_亚洲高清无码在线观看_国产在线视频国产永久2021_国产AV综合第一页一个的一区免费影院黑人_最近中文字幕MV高清在线视频

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

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

3天內不再提示

Prost的最佳實踐經驗

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

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

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

模塊場景和基礎用法

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

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

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

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

首先,我們需要定義動物的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代碼。我們可以使用以下命令來執行此操作:

$ protoc --rust_out . animals.proto

這將生成一個名為animals.rs的文件,其中包含與protobuf定義相對應的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);
}
//  輸出結果:
//  Animal { name: "Tom", age: 3, animal_type: Cat }

在這個示例代碼中,我們定義了一個名為Animal的結構體,并使用prost宏將其與protobuf定義相關聯。我們還定義了一個名為AnimalType的枚舉類型,它與protobuf定義中的枚舉類型相對應。

main函數中,我們創建了一個Animal對象,并將其序列化為字節數組。然后,我們將字節數組反序列化為另一個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的字節數組字段,并使用prost宏的bytes_type屬性將其與chrono庫中的NaiveDateNaiveTime類型相關聯。

自定義編解碼

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

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()));
}
//  輸出結果:
// Ok(Animal { name: "Tom", age: 3, animal_type: Cat })

擴展字段

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

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

以下是一個示例代碼:

syntax = "proto3";

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

    map< string, bytes > extensions = 1000;
}

在這個示例代碼中,我們添加了一個名為extensions的字段,它是一個map類型,可以存儲任何類型的數據。此字段的標簽為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);
}

在這個示例代碼中,我們創建了一個Animal對象,并向其添加了一個名為color的擴展字段。然后,我們將該對象序列化為字節數組,并將其反序列化為另一個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。每個類型都包含與其相關聯的字段。

在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);
}

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

prost最佳實踐

以下是一些使用Prost的最佳實踐經驗:

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

總結

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

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

    關注

    6

    文章

    935

    瀏覽量

    54771
  • 代碼
    +關注

    關注

    30

    文章

    4753

    瀏覽量

    68368
  • rust語言
    +關注

    關注

    0

    文章

    57

    瀏覽量

    3006
收藏 人收藏

    評論

    相關推薦

    嵌入式系統開發實踐經驗分享

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

    有誰能多介紹些AD的實踐經驗嗎?

    有誰能多介紹些AD的實踐經驗嗎?
    發表于 04-03 09:20

    實踐經驗還是理論學習

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

    請問有關于STM32普通IO口模擬操作SMBus通信的相關實踐經驗嗎?

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

    Dockerfile的最佳實踐

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

    工業吸塵吸水機谷歌優化推廣,12年實踐經驗

    `工業吸塵器的外貿怎么推廣,網站優化更有效果工業吸塵吸水機谷歌優化推廣,12年實踐經驗掃地機關鍵詞如何SEO優化到GOOGLE首頁 曾經我以為GOOGLE SEO優化更適合機械制造商,A但現在我
    發表于 10-28 15:53

    編譯器原理及實踐

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

    不同行業客戶如何利用物聯網平臺的實踐經驗案例分析

    物聯網是IT和OT結合的產物,任何以IT為中心的定義都無法描述OT的重要性,反之亦然。在本文中我將不同行業客戶如何利用物聯網平臺的實踐經驗分享給大家。
    的頭像 發表于 12-01 16:46 ?5342次閱讀

    福田汽車對工業互聯網的探索及實踐經驗

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

    在汽車行業多年來戰略與設計上的理論與實踐經驗

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

    OpenHarmony Tech Day技術日 創新教育教學實踐經驗分享

      張澤華就基于OpenHarmony的創新教育教學實踐經驗分享進行演講
    的頭像 發表于 04-25 14:44 ?732次閱讀
    OpenHarmony Tech Day技術日 創新教育教學<b class='flag-5'>實踐經驗</b>分享

    Modbus協議通訊學習仿真器虛擬串口完整套裝實踐經驗總結

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

    使用Koordinator支持異構資源管理和任務調度場景的實踐經驗

    Koordinator 是阿里云基于過去我們建設的統一調度系統中積累的技術和實踐經驗,對外開源了新一代的調度系統。
    的頭像 發表于 08-15 10:09 ?719次閱讀
    使用Koordinator支持異構資源管理和任務調度場景的<b class='flag-5'>實踐經驗</b>

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

    集中電源控制器在實踐中的應用非常廣泛,以下是一些案例研究與實踐經驗分享: 數據中心應用案例:在數據中心中,集中電源控制器可以實現對服務器、網絡設備和存儲設備等關鍵基礎設施的電源集中管理和監控。通過
    的頭像 發表于 01-30 14:59 ?524次閱讀
    訊維集中電源控制器:案例研究與<b class='flag-5'>實踐經驗</b>分享

    中科曙光憑借技術優勢以及實踐經驗獲頒“核心參編單位”證書

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