首頁 > 軟體

詳解Golang ProtoBuf的基本語法總結

2022-10-20 14:02:58

前言

最近專案是採用微服務架構開發的,各服務之間通過gPRC呼叫,基於ProtoBuf序列化協定進行資料通訊,因此接觸學習了Protobuf,本文會對Protobuf的語法做下總結,感興趣的小夥伴們可以參考借鑑,希望對大家能有所幫助。

gRPC的呼叫模型如下:

基本規範

檔案以.proto做為檔案字尾,除結構定義外的語句以分號結尾。

rpc方法定義結尾的分號可有可無。

Message命名採用駝峰命名方式,欄位命名採用小寫字母加下劃線分隔方式。

基本語法

首先看一個簡單的範例:

/*
頭部相關宣告
*/
syntax = "proto3"; // 語法版本為protobuf3.0
package user; // 定義包名,可以為.proto檔案指定包名,防止訊息名衝突。
import "common.proto"; // 匯入common.proto
option go_package = ".;proto";

//服務
service User {
rpc SayHello (SayHelloRequest) returns (SayHelloResponse) {}
}

//定義請求訊息體
message SayHelloRequest {
string name = 1;
int64  role = 2;
}

//定義響應訊息體
message SayHelloResponse {
string message = 1;
}

.proto檔案的第一個非註釋行用於指定語法版本,預設為“proto2”;

package定義包

可以為.proto檔案指定包名,防止訊息名衝突。

import 匯入包

可以通過import匯入其它.proto中定義的訊息;常用於匯入一些公共的資訊。

正常情況下只能使用直接匯入的proto檔案的定義;如果需要使用多級import匯入的檔案,import 可以使用 public 屬性。範例如下:

a.proto

import public "common.proto"; // 注意此處使用的是import public
import "c.proto";

b.proto

import "a.proto";

在b.proto中可以用common.proto中定義的內容,但是不能用c中的定義的內容。

定義Message

定義message使用“message”關鍵字,訊息的欄位宣告由4部分構成:欄位修飾符 欄位型別 欄位名稱 = 標誌號。

格式如下:

message 訊息名稱 {

[欄位修飾符] 欄位型別 欄位名稱 = 標誌號;

}

欄位修飾符

  • singular:預設值,該欄位可以出現0次或者1次(不能超過1次);
  • repeated:該欄位可以重複任意多次(包括0次);

我們可以使用repeated關鍵字來表示動態陣列,範例如下:

message User {
	repeated int64 id = 1;
}

在請求的時候我們可以傳[]int64{1, 2, 3, 4}

欄位型別

關於欄位型別,這裡列舉幾個常用的,其它的如果有需要可以直接網上搜。

型別備註
string字串
double64位元浮點型
float32位元浮點型
int32、int64整型
bool布林型
uint32、uint64無符號整型
sint32、sint64有符號的整形

欄位編號

每個欄位都有一個編號,這些編號是 唯一的。該編號會用來識別二進位制資料中的欄位。編號在1-15範圍內可以用一個位元組編碼表示,在16-2047範圍用兩個位元組表示,所以將15以內得編號留給頻繁出現的欄位可以節省空間。

列舉型別

在定義訊息型別時,我們有可能會為某個欄位預定義值的一個列表,我們可以通過enum來新增一個列舉,為每個可能的值新增一個常數。範例如下:

message UserRequest {
    string name = 1; 
    // 定義性別列舉
    enum Gender {
        UNKNOWN = 0;
        MAN = 1;
        WOMAN = 2;
    }
    // 定義一個列舉欄位
    Gender gender = 2;
}

注意:所有列舉定義都需要包含一個常數對映到0並且作為定義的首行。

巢狀型別

巢狀型別,也就是字面意思,在 message 訊息體中,又巢狀了其它的 message 訊息體,一共有兩種模式,如下:

syntax = "proto3";
message UserResponse {
    message User {
        int64 id = 1;
        string name = 2;
    }
    repeated User users = 1;
} 

如果在外部訊息之外使用內部訊息,則需要使用“outermsg.innermsg”的方式,如,需要在UserResponse外使用User, 則應該使用:

UserResponse.User

Map型別

在返回列表的時候,map型別經常用到,可以使用map關鍵字可以建立一個對映,語法如:

map<key_type, value_type> map_field = N;
  • key_type 只能是整數或字串,enum不能作為key_type;
  • value_type 是除了對映(map)意外的任意型別;

範例:

message User {
    int64 id = 1;
    string name = 2;
}

map[int64, User] users = 1;

定義Service

如果想在RPC中使用已經定義好的訊息型別,可以在.proto檔案中定一個訊息服務介面,使用service關鍵字進行服務定義,如:

service User {
rpc SayHello (SayHelloRequest) returns (SayHelloResponse) {}
}

到此這篇關於詳解Golang ProtoBuf的基本語法總結的文章就介紹到這了,更多相關Golang ProtoBuf內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com