proto文件應該如何撰寫

什么是.pb.h 和 .pb.cc 文件?

protobuf的核心是一個.proto文件,我們自定義一個.proto來創建我們的協議數據,然后使用protocol buffer 編譯器工具編譯生成兩個"文件名.pb.cc""文件名.pb.h"的文件。

Protocol Buffers,是Google公司開發的一種數據格式,類似于XML和json,是一種用于數據傳輸時將數據序列化和反序列化的一個跨平臺(支持目前主流的各種語言)工具庫,可用于數據存儲、通信協議等方面。它不依賴于語言和平臺并且可擴展性極強。

作用:

  • Protobuf支持多種編程語言,如Java、C++、Python等。你可以使用protobuf編譯器將.proto文件編譯成對應語言的源代碼,從而實現跨平臺、跨語言的數據交換。
  • 生成的代碼提供了序列化和反序列化的功能,可以很容易地將數據結構轉換為字節流,或將字節流轉換為數據結構。
  • 使用protobuf編譯器從.proto文件生成代碼,可以省去手動編寫序列化和反序列化代碼的繁瑣工作,減少出錯的可能性。
  • 生成的代碼通常包含數據結構的訪問器(accessor)和修改器(mutator),使得操作數據結構更加方便。

??????? 總結:使用protobuf并通過.proto文件定義數據協議,然后編譯生成對應的源代碼文件,可以帶來高效性、靈活性、跨平臺性、跨語言支持、自動生成代碼、兼容性、可擴展性以及減少網絡帶寬和存儲空間消耗等好處。這些優點使得protobuf在分布式系統、網絡通信、數據存儲等領域得到了廣泛的應用。并且Protobuf支持向后兼容性和向前兼容性。向后兼容性意味著新版本的程序可以讀取舊版本的數據;向前兼容性意味著舊版本的程序可以選擇性地忽略新版本數據中的新增字段。

??????? 通俗來說:想象一下,你正在開發一個應用,這個應用需要在不同的設備或不同的軟件之間傳輸數據。這些數據可能包含用戶的信息、訂單詳情、圖片描述等等。但是,每臺設備或每種軟件都有它自己的方式來理解和存儲這些數據,這就好像大家都說不同的語言,無法直接溝通。現在,你希望有一種方式,能讓所有的設備或軟件都理解并使用同一種數據格式。這就是protobuf的作用了。

?? .proto文件就是protobuf的“藍圖”或“模板”。你可以在這個文件里,用簡單明了的語法定義你的數據結構,比如一個用戶信息可能包括姓名、年齡、地址等字段。然后,你可以使用protobuf的編譯器(就像是一個翻譯官)將這個.proto文件“翻譯”成各種編程語言都可以理解的代碼(比如C++的.pb.cc.pb.h文件)。

????????這些生成的代碼就像是一個“說明書”,它告訴每種語言的程序,如何理解這個數據結構,如何把這個數據結構轉換成可以傳輸的數據(這個過程叫做序列化),以及如何把接收到的數據轉換回原來的數據結構(這個過程叫做反序列化)。

使用protobuf的好處有很多:

  1. 大家都懂:所有的設備或軟件都可以使用同一種數據格式,就像大家都說同一種語言,溝通起來就方便了。
  2. 節省資源:protobuf使用了一種緊湊的二進制格式,所以傳輸的數據會更小,節省網絡帶寬,也節省存儲空間。
  3. 容易修改:如果以后需要添加或修改數據字段,你只需要修改.proto文件,然后重新“翻譯”一下就可以了,不需要改動已經寫好的代碼。
  4. 安全可靠:protobuf在序列化和反序列化的過程中,會對數據進行校驗,確保數據的完整性和安全性。

所以,.proto文件和protobuf就是幫助我們實現不同設備或軟件之間高效、安全、方便的數據交換的工具。

模板

編寫 Protocol Buffers(protobuf)的 .proto 文件時,通常遵循以下步驟和最佳實踐:

1.指定語法版本:
??? 首先,指定你正在使用的 protobuf 語法版本。目前主要有 proto2 和 proto3 兩種版本。

syntax = "proto3"; // 或者 "proto2"

2.定義包名:
為你的 .proto 文件定義一個包名,這有助于防止不同項目中的消息類型名稱沖突。

package your.package.name;

3.導入其他 .proto 文件:
如果你的 .proto 文件需要使用在其他 .proto 文件中定義的消息類型,你需要使用 import 語句導入它們。

import "other_protos/other.proto";

4.定義消息類型:
在 .proto 文件中定義你的消息類型。消息類型由字段組成,每個字段都有名稱、類型和唯一的標識符(標簽)。

message Person { ?
??? string name = 1; ?
??? int32 id = 2; ?
??? string email = 3; ?
?
??? enum PhoneType { ?
??????? MOBILE = 0; ?
??????? HOME = 1; ?
??????? WORK = 2; ?
??? } ?
?
??? message PhoneNumber { ?
??????? string number = 1; ?
??????? PhoneType type = 2; ?
??? } ?
?
??? repeated PhoneNumber phones = 4; ?

}

5.定義字段規則:
在 proto3 中,字段規則只有 required(已被移除)、optional(也被移除,所有字段默認為可選)和 repeated(表示字段可以重復,即數組)。但在 proto3 中,通常不需要顯式指定 optional,因為所有字段默認就是可選的。

在 proto2 中,你需要明確指定字段是 required、optional 還是 repeated。但請注意,required 字段在 proto3 中已被移除。

6.定義服務(可選):
如果你的 .proto 文件用于定義 gRPC 服務,你可以在其中定義服務及其方法。

service Greeter { ?
??? rpc SayHello (HelloRequest) returns (HelloReply) {} ?
}?
message HelloRequest { ?
??? string name = 1; ?
}?
message HelloReply { ?
??? string message = 1; ?

}

7.使用保留字段:
如果你刪除了某個字段,并且之后可能會重用該字段的標識符,你應該使用 reserved 關鍵字來保留該標識符,以確保不會在未來發生字段標識符沖突。

message Foo { ?
??? reserved 2, 15, 9 to 11; ?
??? reserved "foo", "bar"; ?
?
??? int32 baz = 1; ?

}

8.注釋:
使用 // 添加單行注釋,或使用 /* ... */ 添加多行注釋。

9.編譯 .proto 文件:
使用 Protocol Buffers 編譯器 protoc 將 .proto 文件編譯成你需要的編程語言的源代碼文件。

//bash

protoc --python_out=. your_file.proto

上面的命令將 your_file.proto 編譯成 Python 代碼。根據你的需要,你可以使用不同的插件(如 --cpp_out=、--java_out= 等)來生成不同編程語言的代碼。

測試和驗證:
在將生成的代碼集成到你的項目中之前,確保通過編寫單元測試和集成測試來驗證 .proto 文件的定義和生成的代碼的正確性。

例子:

syntax = "proto2";package InterVariable;
//這定義了一個名為 InterVariable 的包。在生成的 C++ 代碼中,所有消息類都將被放置在這個命名空間內。message VariableList{
required string name = 1;
required int32 row = 2;
required int32 col = 3;
required int32 type = 4;
repeated string value = 5;//把變量的值都用string類型存儲起來,使用stringstream將string類型轉換成需要的類型
}
message VariableResquest{
required int32 option = 1;//0 -> exit  1 -> modify 2-> select 3 -> modify + select
repeated VariableList variable_resquest_modify = 2;
repeated VariableList variable_resquest_select = 3;
}message VariableResponse{
optional string res = 1;//如果是修改的請求,用res返回“Successful!”或者“Failed!"給客戶端
repeated VariableList variable_response = 2;//如果是查詢請求,返回的select的信息即查詢的所有變量組成的鏈表給客戶端
}

消息類型:VariableResquest

  • option:一個必需的32位整數字段,用于表示請求的選項。注釋中說明了該字段的可能值及其含義(0 表示退出,1 表示修改,2 表示選擇,3 表示修改和選擇)。
  • variable_resquest_modify:一個可重復的 VariableList 字段,用于包含需要修改的變量列表。
  • variable_resquest_select:一個可重復的 VariableList 字段,用于包含需要選擇的變量列表。

消息類型:VariableResponse

  • res:一個可選的字符串字段,用于在修改請求時返回成功或失敗的消息。
  • variable_response:一個可重復的 VariableList 字段,用于在查詢請求時返回查詢到的變量列表。

總結:

????????定義了一個用于處理變量請求和響應的消息結構。VariableList 消息用于表示一個變量,包括其名稱、位置(行和列)、類型以及值。VariableResquest 消息用于表示一個請求,包括請求的類型(修改、選擇等)以及相關的變量列表。VariableResponse 消息用于表示對請求的響應,包括響應消息和(在查詢請求時)返回的變量列表。

相關解釋和說明

在 Protocol Buffers(protobuf)中,字段的修飾符決定了字段的特性。在 proto3 語法中,required 已經被移除,而 optional 字段也沒有明確的修飾符(因為所有字段默認都是可選的)。但在 proto2 語法中,這三個修飾符都存在,并具有以下含義:

  1. required(僅在 proto2 中):
    required 字段表示該字段在序列化消息時必須存在,并且在解析消息時也必須存在。如果消息缺少 required 字段,解析將失敗并拋出異常。由于這個嚴格的要求,required 字段在 proto3 語法中被移除了,因為 proto3 的設計更偏向于簡單性和向后兼容性。

  2. optional(在 proto2 中,但在 proto3 中默認):
    optional 字段表示該字段在序列化消息時可以存在,也可以不存在。在解析消息時,如果該字段不存在,它的值將被設置為默認值(對于基本類型,默認值通常是零或空字符串)。在 proto3 語法中,所有字段默認都是 optional 的,即使沒有顯式指定。

  3. repeated
    repeated 字段表示該字段可以包含任意數量的元素(包括零個)。在序列化消息時,這些元素會被重復地寫入。在解析消息時,你可以通過迭代這個字段來獲取所有的元素。repeated 字段常用于表示數組或列表。

三種修飾符的使用場景示例:

1.required

使用場景:當某個字段對于消息來說是必不可少的,如果缺少這個字段,消息就不完整或無效。

例子:假設你正在設計一個表示“人”的消息格式,其中“名字”是一個必須存在的字段。

message Person {  required string name = 1; // 名字是必須的  int32 age = 2; // 年齡是可選的  }

在這個例子中,如果序列化一個 Person 消息時沒有包含 name 字段,那么序列化將失敗。同樣,如果嘗試解析一個不包含 name 字段的 Person 消息,解析也會失敗。

2.optional

使用場景:當某個字段對于消息來說是可選的,即使缺少這個字段,消息仍然是完整和有效的。

例子:在上面的 Person 消息中,age 字段是可選的。這意味著你可以序列化一個只有 name 字段的 Person 消息,而不包含 age 字段。

proto3 中,由于所有字段默認都是 optional 的,所以你不需要顯式地使用 optional 修飾符。

3.repeated

使用場景:當某個字段可以包含多個值時,例如一個人的多個電話號碼或一個項目的多個任務。

例子:假設你正在設計一個表示“聯系人”的消息格式,其中一個人可以有多個電話號碼。

message PhoneNumber {  string number = 1;  enum Type {  HOME = 0;  WORK = 1;  MOBILE = 2;  }  Type type = 2;  
}  message Person {  required string name = 1;  repeated PhoneNumber phones = 2; // 一個人可以有多個電話號碼  
}

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

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

相關文章

K-Planes代碼記錄

隨記 原文 K-Planes: Explicit Radiance Fields in Space, Time, and Appearance,又要換baseline,可是效果不好能怎么辦呢,我可不可以發瘋。k-planes的代碼又是非常工程瑣碎的,大佬的代碼果然不顧小白死活。隨便記錄下整個過程。…

制造型企業生產管理的技巧,你都用過哪些?

作為管理者,一談到生產管理,你可能會想到很多生產過程中的問題:訂單準交率不高、計劃達成率不高、生產效率低、再制品太多、生產周期長等等一系列問題;如果你不僅僅是一名管理者,你還是一名企業主,你甚至經…

實踐Go的命令模式

簡介 現在的軟件系統往往是分層設計。在業務層執行一次請求時,我們很清楚請求的上下文,包括,請求是做什么的、參數有哪些、請求的接收者是誰、返回值是怎樣的。相反,基礎設施層并不需要完全清楚業務上下文,它只需知道…

Bootstrap更改默認的“請在電子郵件地址中包含@”

摘要: 今天開發一個外貿系統,必須全部英文的,但是使用到bootatrp 4的input標簽的type"email"輸入沒有含“”符號時會提示:“請在電子郵件地址中包含”中文提示!一開始以為是中國下載的谷歌是瀏覽器自帶的提示…

[思考記錄.產品改進]假如異常日志可以自動上報

最近考慮日志收集的事情,主要出發點是: 1、在問題出現后能方便快速地收集相關的線索和證據,幫助快速定位和解決問題。因為反饋問題往往在發生之后,如果在這個時候能快速方便地拿到有用信息是件很舒服的事情,而在獲取日…

AIGC重塑創意設計:不僅能帶來新技術,更能引發新思考

隨著科技的飛速發展,AIGC(生成式人工智能)已經逐漸成為創意設計領域的一股新勢力。從影視制作到游戲設計,從平面廣告到數字媒體,AIGC的影響力無處不在,它不僅帶來了全新的技術手段,更在深層次上…

Linux-筆記 嵌入式gdb遠程調試

目錄 前言 實現 1、內核配置 2、GDB移植 3、準備調試程序 4、開始調試 前言 gdb調試器是基于命令行的GNU項目調試器,通過gdb工具我們可以實現許多調試手段,同時gdb支持多種語言,兼容性很強。 在桌面 Linux 系統(如 Ubuntu、Cent…

跨越地域界限:Eureka實現跨區域服務發現全解析

跨越地域界限:Eureka實現跨區域服務發現全解析 在微服務架構的浪潮中,服務的分布式部署已成為常態。隨著業務的全球擴展,服務往往需要跨區域甚至跨國界進行部署。在這樣的背景下,服務發現機制面臨著新的挑戰——如何實現不同區域…

如何在服務器中找到數據庫文件路徑

在服務器中找到數據庫文件路徑的具體方法取決于您所使用的數據庫管理系統和服務器的操作系統。以下是一些常見的數據庫系統(如MySQL、Microsoft SQL Server、Oracle、PostgreSQL和MongoDB)的文件路徑查找方法的詳細步驟: MySQL 通過命令行查…

Redis基礎教程(三):redis命令

💝💝💝首先,歡迎各位來到我的博客,很高興能夠在這里和您見面!希望您在這里不僅可以有所收獲,同時也能感受到一份輕松歡樂的氛圍,祝你生活愉快! 💝&#x1f49…

08 - Python面向對象編程進階

面向對象進階 在前面的章節我們已經了解了面向對象的入門知識,知道了如何定義類,如何創建對象以及如何給對象發消息。為了能夠更好的使用面向對象編程思想進行程序開發,我們還需要對Python中的面向對象編程進行更為深入的了解。 property裝…

六西格瑪綠帶培訓的證書有什么用處?

近年來,六西格瑪作為一套嚴謹而系統的質量管理方法,被廣泛運用于各行各業。而六西格瑪綠帶培訓證書,作為這一方法論中基礎且重要的認證,對于個人和企業而言,都具有不可忽視的價值。本文將從多個角度深入探討六西格瑪綠…

重寫功能 rewrite

Nginx服務器利用 ngx_http_rewrite_module 模塊解析和處理rewrite請求,此功能依靠 PCRE(perl compatible regular expression),因此編譯之前要安裝PCRE庫,rewrite是nginx服務器的重要功能之 一,用于實現URL的重寫,URL的…

充電寶口碑哪個好?好用充電寶品牌有哪些?好用充電寶推薦

充電寶作為我們日常生活和出行的重要伙伴,其品質和性能直接影響著我們的使用體驗。今天,就來和大家探討一下充電寶口碑哪個好,為大家盤點那些備受贊譽的好用充電寶品牌,并向您推薦幾款值得入手的充電寶,外出時不再擔心…

mac英語學習工具:Eudic歐路詞典 for Mac 激活版

Eudic歐路詞典是一款非常受歡迎的英語學習軟件,它提供了豐富的詞匯解釋、例句、同義詞、反義詞等功能,幫助用戶更好地理解和掌握英語單詞。 以下是Eudic歐路詞典的一些主要特點: 海量詞匯庫:Eudic歐路詞典擁有龐大的詞匯庫&#…

flutter photo_manager 報錯:Error: ‘DecoderCallback‘ isn‘t a type.

看看是不是你的photo_manager版本少于3.0。如果是少于3.0,請及時升級到3.0及以上版本,同時因為photo_manager3.0不再提供 AssetEntityImageProvider 這個方法,會導致報錯,不要慌,請添加下方的庫即可解決問題&#xf…

為什么人人都要懂一些銷售思維

創業看事情的高度、考慮的維度比做銷售更高、更復雜、更全面,銷售思維、銷售方法更多時候用在解決局部問題,幫我們打局部戰爭,它是術。 但是,我仍然認為,銷售思維是一種很有用、有效、有力量、必要的思維。我們每個人…

面試題002-Java-Java集合

面試題002-Java-Java集合 目錄 面試題002-Java-Java集合題目自測題目答案1. 說說 List,Set,Map 三者的區別?三者底層的數據結構?2. 有哪些集合是線程不安全的?怎么解決呢?3. 比較 HashSet 、LinkedHashSet 和 TreeSet 三者的異同&…

簡過網:考一建需要報培訓班嗎?報班費用是多少錢

近幾年來,越來越多的朋友都開始關注和參與備考一建,那么,大家在備考一建時,都報培訓班了嗎?報班的費用是多少錢?接下來,我們一塊來了解一下吧? ? 一、考一建需要報培訓班嗎&#…

【Jetpack】Lifecycle之自定義LifecycleOwner

Lifecycle設計講解 Lifecycle的設計其實十分簡單,主要就是Lifecycle對象和LifecycleOwner接口 Lifecycle用于記錄對象的生命周期,以及在生命周期發生改變時通知外部 LifecycleOwner用于表示對象具備生命周期管理能力 LifecycleOwner的實現方式很簡單&…