Protobuf 学习 | 青训营笔记

93 阅读2分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 9 天

syntax = "proto3";

package user;

option go_package = "./comment";

//请求

message getFavoriteCountByVideoIdReq{
  int64 videoId = 1;
}

//响应
message getFavoriteCountByVideoIdReply{
  int64 count = 1;
}


service like {
  //根据videoId获取视屏评论总数
  rpc getCommentCountByVideoId(getFavoriteCountByVideoIdReq) returns(getFavoriteCountByVideoIdReply);

}

代码解释

Filename: addressbook.proto 这一行是注释,语法类似于C++

syntax="proto2"; 表明使用protobuf的编译器版本为v2,目前最新的版本为v3

package addressbook; 声明了一个包名,用来防止不同的消息类型命名冲突,类似于 namespace

import "src/help.proto"; 导入了一个外部proto文件中的定义,类似于C++中的 include 。不过好像只能import当前目录及当前目录的子目录中的proto文件,比如import父目录中的文件时编译会报错(Import "../xxxx.proto" was not found or had errors.),使用绝对路径也不行,尚不清楚原因,官方文档说使用 -I=PATH 或者 --proto_path=PATH 来指定import目录,但实际实验结果表明这两种方式指定的是将要编译的proto文件所在的目录,而不是import的文件所在的目录。

message 是Protobuf中的结构化数据,类似于C++中的类,可以在其中定义需要处理的数据

required string name = 1; 声明了一个名为name,数据类型为string的required字段,字段的标识号为1

protobuf一共有三个字段修饰符:

   - required:该值是必须要设置的;  

    - optional :该字段可以有0个或1个值(不超过1个);  

   - repeated:该字段可以重复任意多次(包括0次),类似于C++中的list; 

使用建议:除非确定某个字段一定会被设值,否则使用optional代替required。

string 是一种标量类型,protobuf的所有标量类型请参考文末的标量类型列表。

name 是字段名,1 是字段的标识号,在消息定义中,每个字段都有唯一的一个数字标识号,这些标识号是用来在消息的二进制格式中识别各个字段的,一旦开始使用就不能够再改变。标识号的范围在:1 ~ 229 - 1,其中[19000-19999]为Protobuf预留,不能使用。

Person 内部声明了一个enum和一个message,这类似于C++中的类内声明,Person外部的结构可以用 Person.PhoneType 的方式来使用PhoneType。当使用外部package中的结构时,要使用 pkgName.msgName.typeName 的格式,每两层之间使用'.'来连接,类似C++中的"::"。

optional PhoneType type = 2 [default = HOME]; 为type字段指定了一个默认值,当没有为type设值时,其值为HOME。
另外,一个proto文件中可以声明多个message,在编译的时候他们会被编译成为不同的类。