[Protobuf]常見數據類型以及使用注意事項

[Protobuf]常見數據類型以及使用注意事項
@水墨不寫bug


在這里插入圖片描述


文章目錄

  • 一、基本數據類型
    • 1、字段
    • 2、字段的修飾規則
  • 二、自定義數據類型
    • 1、message類型
    • 2、enum類型
    • 3、Any類型
    • 4、oneof類型
    • 5、map類型
  • 三、小工具
    • 1.hexdump
    • 2.decode
  • 四、注意事項


一、基本數據類型

protobuf 支持多種基礎數據類型,常用的有:

類型說明可選值范圍(部分)
double64位浮點數±1.7E±308
float32位浮點數±3.4E±38
int32使用變長編碼[1]。負數的編碼效率較低?若字段可能為負值,應使用 sint32 代替-2^31 到 2^31-1
int64使用變長編碼[1]。負數的編碼效率較低?若字段可能為負值,應使用 sint64 代替-2^63 到 2^63-1
uint32無符號32位整型 ,使用變長編碼[1]0 到 2^32-1
uint64無符號64位整型 ,使用變長編碼[1]0 到 2^64-1
sint32有符號32位整型(高效編碼負數)-2^31 到 2^31-1
sint64有符號64位整型(高效編碼負數)-2^63 到 2^63-1
fixed32定長 4 字節。若值常大于2^28 則會比 uint32 更高效。0 到 2^32-1
fixed64定長 8 字節。若值常大于2^56 則會比 uint64 更高效。0 到 2^64-1
sfixed32固定32位有符號整型(固定長度編碼)-2^31 到 2^31-1
sfixed64固定64位有符號整型(固定長度編碼)-2^63 到 2^63-1
bool布爾值true/false
string包含 UTF-8 和 ASCII 編碼的字符串,長度不能超過 2^32任意長度字符串
bytes可包含任意的字節序列但長度不能超過 2^32任意長度字節數組

注:[1] 變長編碼是指:經過protobuf 編碼后,原本4字節或8字節的數可能會被變為其他字節數


1、字段

在定義一個字段之后,會給字段設置一個唯一標記值同一個消息體內,字段標記值不能重復。

message PersonInfo
{int id = 1;string name = 1;//(字段標志重復)
}

消息體內的消息體可以重新計算標記值:

message PersonInfo
{int id = 1;string name = 2;message Phone{string number = 1;//(重新計算標記值)}
}

其次:

字段名稱命名規范:全小寫字母,多個字母之間用 _ 連接。
字段類型分為:基本數據類型 和 特殊類型(包括枚舉enum、消息類型message等)。
字段唯?編號:用來標識字段,?旦開始使用就不能夠再改變

字段編號的范圍為:

1 ~ 536,870,911 (2^29 - 1) ,其中 19000 ~ 19999 不可用

范圍為 1 ~ 15 的字段編號需要一個字節進行編碼, 16 ~ 2047內的數字需要兩個字節進行編碼。編碼后的字節不僅只包含了編號,還包含了字段類型。所以 1 ~ 15要用來標記出現非常頻繁的字段,要為將來有可能添加的、頻繁出現的字段預留一些出來。

2、字段的修飾規則

singular:消息中可以包含該字段零次或?次(不超過?次)。 proto3 語法中,字段默認使用該規則。
repeated:消息中可以包含該字段任意多次(包括零次),其中重復值的順序會被保留。可以理解為定義了?個數組。


二、自定義數據類型

1、message類型

一個message類型被protoc編譯器編譯之后形成對應class。message可以嵌套message,同一層message,字段編號不能重復。message可作為類型來使用,對應class類型組合。

2、enum類型

定義enum類型的值,直接用名稱+常量表示:
例如:

enum PhoneType //枚舉名稱的名稱建議用駝峰命名
{MP = 0;TEL = 1;
}

常量值從0開始,只能為正值,不能為負。枚舉類型也可定義在message體內部。

在同一層級內,不同的枚舉類型內的同名常量值不能相同:
例如:

enum PhoneType
{MP = 0;TEL = 1;
}
enum PhoneTypeCopy
{MP = 0;
}

否則會報錯重定義。
改為不重名即可:

enum PhoneType
{MP = 0;TEL = 1;
}
enum PhoneTypeCopy
{MP_C = 0;
}

類似的還有兩個沒有限制package的文件,import后也會出現上述類似問題。
解決方法是加上package限制。

3、Any類型

泛型類型,可以存放任意類型的數據。
是google直接寫好的,使用前需要

import "google/protobuf/any.proto";

聲明變量的格式如下:

message PeopleInfo
{google.protobuf.Any data = 0;
}

使用any類型需要常用的接口:

// .google.protobuf.Any data = 4;
bool has_data() const;//是否有數據
void clear_data();//清除數據
const ::PROTOBUF_NAMESPACE_ID::Any& data() const;//get
::PROTOBUF_NAMESPACE_ID::Any* mutable_data();//set
//把任意類型轉化為any類型
bool PackFrom(const ::PROTOBUF_NAMESPACE_ID::Message& message);
//重載類型
bool PackFrom(const ::PROTOBUF_NAMESPACE_ID::Message& message,::PROTOBUF_NAMESPACE_ID::ConstStringParam type_url_prefix);
//把any類型轉化為任意類型
bool UnpackTo(::PROTOBUF_NAMESPACE_ID::Message* message) const;
//判斷Any類型是否是T類型
template<typename T> bool Is() const {return _impl_._any_metadata_.Is<T>();}

4、oneof類型

被oneof聲明的多個字段只能保留最后被設置的一個:

oneof other_contact
{string qq = 5;string wechat = 6;
}

qq和微信字段只會保留最后一次被設置的值。

oneof內部不能使用repeated修飾字段。

常用方法包括clear,set,get。不同的是多了一個has方法,用來表明是否有這個方法。

在對應生成的Cpp代碼中,oneof類型定義的多個類型會被轉化為一個enum類型。內部除了oneof內部的類型之外,還有一個NOT_SET = 0常量值。

5、map類型

類似于C++的map,定義protobuf的map需要注意,key_type只能是float,bytes類型之外的標量類型。val_type可以是任意類型。
map不能被repeated修飾。
設置的key-val鍵值對是無序的。

常用方法:size,clear,get,set。


三、小工具

1.hexdump

hexdump是Linux下的?個二進制文件查看工具,它可以將二進制文件轉換為ASCII、八進制、十進制、十六進制格式進行查看。
-C: 表示每個字節顯示為16進制和相應的ASCII字符

這個工具意義在于把protobuf序列化后的二進制轉化為ASCII,便于查看。

2.decode

ProtoBuf 提供的一個命令選項 --decode ,表表示從標準輸入中讀取給定類型的二進制消息,并將其以文本格式寫入標準輸出。 消息類型必須在 .proto 文件或導入的文件中定義。
在這里插入圖片描述

protoc --decode=contacts.Contacts contacts.proto < contacts.bin

這條命令用于解碼一個用 Protocol Buffers(protobuf)序列化后的二進制文件 contacts.bin,并將其內容以可讀的文本格式輸出。下面是這條命令的詳細解釋:

  1. protoc
    這是 Protocol Buffers 的編譯器命令行工具,用于編譯 .proto 文件和處理 protobuf 數據。

  2. –decode=contacts.Contacts
    這個參數的意思是用 .proto 文件中定義的 contacts.Contacts 這個消息類型來解碼輸入的數據。

    • contacts 是 proto 文件中的包名(package)。
    • Contacts 是 proto 文件中定義的消息類型(message)。
  3. contacts.proto
    這是 protobuf 的協議文件,里面定義了數據結構(消息類型、包名等)。protoc 會用它來知道怎么解析二進制數據。

  4. < contacts.bin
    這表示將 contacts.bin 文件中的二進制數據(用 protobuf 序列化過的)作為標準輸入傳給 protoc


四、注意事項

  1. 字段編號(tag)不可輕易變更
    字段編號 是二進制格式的唯一標識,不能隨意修改或復用,否則會導致兼容性問題。

  2. 盡量避免刪除字段
    如果需要廢棄字段,可用 reserved 關鍵字保留該 tag 和字段名。

  3. 字段類型不能隨意更改
    特別是從一種類型改為不兼容的另一種類型(如 int32 改為 string),會導致解析錯誤。

  4. repeated 字段適合表達數組或列表
    表示 0 個或多個同類型數據項。例如 repeated int32 scores。

  5. 嵌套 message 和 enum
    可以在 message 內部定義子 message 或 enum,便于結構化復雜數據。

  6. 避免使用 float/double 存儲精確金額
    由于浮點數精度問題,金額等精確數據建議用 int64/uint64 表示最小單位(如分、厘)。

  7. bytes 與 string 區別
    string 專為 UTF-8 文本,bytes 則可存儲任意二進制數據,如圖片、加密內容等。


完~
未經作者同意禁止轉載
在這里插入圖片描述


本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/85331.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/85331.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/85331.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

JS分支和循環

程序的執行順序 在程序開發中&#xff0c;程序有三種不同的執行順序 1.順序執行 2.分支執行 3.循環執行 程序的代碼塊 <script>//一個代碼塊{var num11var num22var num3num1num2}//一個休想var info{name:"chen",age:18} 1.if分支語句&#xff08;單分支語句&…

Android 開發 Kotlin 全局大喇叭與廣播機制

在 Android 開發中&#xff0c;廣播機制就像一個神通廣大的 “消息快遞員”&#xff0c;承擔著在不同組件間傳遞信息的重任。Kotlin 語言的簡潔優雅更使其在廣播機制的應用中大放異彩。今天&#xff0c;就讓我們一同深入探索 Android 開發中 Kotlin 全局大喇叭與廣播機制的奧秘…

rabbitmq AI復習

RabbitMq rabbitmq &#x1f9d1;?&#x1f4bb; User 幫我復習rabbitmq相關知識&#xff0c;我是一個經驗豐富的程序員 &#x1f916; Assistant 好的&#xff01;很高興能通過這種方式幫你復習或學習 RabbitMQ 的知識。按照你說的流程&#xff0c;我們從完全零基礎開始&…

計算機視覺---YOLOv5

YOLOv5理論講解 一、YOLOv5 整體架構解析 YOLOv5 延續了 YOLO 系列的 單階段目標檢測框架&#xff0c;包含 主干網絡&#xff08;Backbone&#xff09;、頸部網絡&#xff08;Neck&#xff09; 和 檢測頭&#xff08;Head&#xff09;&#xff0c;但在結構設計上更注重 輕量化…

C++多重繼承詳解與實戰解析

#include <iostream> using namespace std; //基類&#xff0c;父類 class ClassA { public:void displayA() {std::cout << "Displaying ClassA" << std::endl;}void testFunc(){std::cout << "testFunc ClassA" << std::e…

單細胞注釋前沿:CASSIA——無參考、可解釋、自動化細胞注釋的大語言模型

細胞類型注釋是單細胞RNA-seq分析的重要步驟&#xff0c;目前有許多注釋方法。大多數注釋方法都需要計算和特定領域專業知識的結合&#xff0c;而且經常產生不一致的結果&#xff0c;難以解釋。大語言模型有可能在減少人工輸入和提高準確性的同時擴大可訪問性&#xff0c;但現有…

STM32Cubemx-H7-17-麥克納姆輪驅動

前言 --末尾右總體的.c和.h 本篇文章把麥克納姆輪的代碼封裝到.c和.h&#xff0c;使用者只需要根據輪子正轉的方向&#xff0c;在.h處修改定義方向引腳&#xff0c;把輪子都統一正向后&#xff0c;后面的輪子驅動就可以正常了&#xff0c;然后直接調用函數驅動即可。 設置滿…

文檔核心結構優化(程序C++...)

文檔核心結構優化 一、文檔核心結構優化二、C關鍵特性詳解框架2.1 從C到C的范式遷移 三、深度代碼解析模板3.1 現代C特性分層解析 四、C vs C 關鍵差異矩陣五、交互式文檔設計策略5.1 三維學習路徑5.2 代碼缺陷互動區 六、現代C特性演進圖七、性能優化可視化呈現&#xff08;深…

PyTorch ——torchvision數據集使用

如果下載的很慢&#xff0c;可以試試下面這個

純前端實現圖片偽3D視差效果

作者&#xff1a;vivo 互聯網前端團隊- Su Ning 本文通過depth-anything獲取圖片的深度圖&#xff0c;同時基于pixi.js&#xff0c;通過著色器編程&#xff0c;實現了通過深度圖驅動的偽3D效果。該方案支持鼠標/手勢與手機陀螺儀雙模式交互&#xff0c;在保證性能的同時&#x…

英語寫作中“專注于”focus on、concentrate的用法

Focus on在論文寫作中常用&#xff0c;指出研究點&#xff0c;例如&#xff1a; There are three approaches to achieving ID authentication. Our study will focus on ……&#xff08;有三種途徑實現身份認證&#xff0c;我們的研究專注于……&#xff09; concentrate &…

go環境配置

下載對應版本的 go 版本 https://go.dev/dl/ 配置 vim ~/.zshrc export GOROOT/usr/local/go export PATH$PATH:$GOROOT/binsource ~/.zshrc >>>>>> go versiongoland 配置&#xff1a; &#x1f50d; 一、什么是GOPATH&#xff1f; GOPATH 是舊的項目結…

AI Agent智能體:底層邏輯、原理與大模型關系深度解析·優雅草卓伊凡

AI Agent智能體&#xff1a;底層邏輯、原理與大模型關系深度解析優雅草卓伊凡 一、AI Agent的底層架構與核心原理 1.1 AI Agent的基本構成要素 AI Agent&#xff08;人工智能代理&#xff09;是一種能夠感知環境、自主決策并執行行動的智能系統。其核心架構包含以下關鍵組件…

【手搓一個原生全局loading組件解決頁面閃爍問題】

頁面閃爍效果1 頁面閃爍效果2 封裝一個全局loading組件 class GlobalLoading extends HTMLElement {constructor() {super();this.attachShadow({ mode: open });}connectedCallback() {this.render();this.init();}render() {this.shadowRoot.innerHTML <style>.load…

unix/linux source 命令,其高級使用

就像在物理學中,掌握了基本定律后,我們可以開始研究更復雜的系統和現象,source 的高級用法也是建立在對其基本行為深刻理解之上的。 讓我們一起探索 source 的高級應用領域: 1. 條件化加載 (Conditional Sourcing) 根據某些條件來決定是否 source 一個文件,或者 source…

DexGarmentLab 論文翻譯

單個 專家 演示 裝扮 15 任務 場景 2500+ 服裝 手套 棒球帽 褲子 圍巾 碗 帽子 上衣 外套 服裝-手部交互 捕捉 搖籃 夾緊 平滑 任務 ...... 投擲 懸掛 折疊 ... 多樣化位置 ... 多樣化 變形 ... 多樣化服裝形狀 類別級 一般化 類別級(有或沒有變形) 服裝具有相同結構 變形 生…

WPF-Prism學習筆記之 “導航功能和依賴注入“

新建空白模板(Prism) 新建好后會有自動創建ViewModels和Views 在"MainWindow.xaml"文件里面標題去綁定了一個屬性"Title"&#xff0c;而"MainWindowViewModel.cs"里面繼承一個非常重要的"BindbleBase"(prism框架里面非常重要的)。所以…

《C++初階之入門基礎》【C++的前世今生】

【C的前世今生】目錄 前言&#xff1a;---------------起源---------------一、歷史背景二、橫空出世---------------發展---------------三、標準立世C98&#xff1a;首個國際標準版本C03&#xff1a;小修訂版本 四、現代進化C11&#xff1a;現代C的開端C14&#xff1a;對C11的…

YOLOv5-入門篇筆記

1.創建環境 conda create -n yolvo5 python3.8 去pytorch.org下載1.8.2的版本。 pip --default-timeout1688 install torch1.8.2 torchvision0.9.2 torchaudio0.8.2 --extra-index-url https://download.pytorch.org/whl/lts/1.8/cu111 github上下載yolov5的zip pip --def…

【PostgreSQL 03】PostGIS空間數據深度實戰:從地圖服務到智慧城市

PostGIS空間數據深度實戰&#xff1a;從地圖服務到智慧城市 關鍵詞 PostGIS, 空間數據庫, 地理信息系統, GIS, 空間查詢, 地理分析, 位置服務, 智慧城市, 空間索引, 坐標系統 摘要 PostGIS是PostgreSQL的空間數據擴展&#xff0c;它將普通的關系數據庫轉變為強大的地理信息系統…