proto文件详解

一、message介绍

message:protobuf中定义一个消息类型是通过关键字message字段指定的。消息就算需要传输的数据格式的定义。message关键字类似于C++中的class,Java中的Class,go中的struct

例如:

message User{
	string username=1;
	int32 age=2;
}

在消息中承载的数据分别对应于每一个字段。

其中每个字段都有一个名字和一种类型。

二、字段规则

字段作用
required消息体中必填字段,不设置会导致编解码异常。一般不填就认为是必填字段了
optional消息体中可选字段。生成的是对应的指针
repeated消息体中可重复字段,重复的值的顺序会被保留,在go中重复的会被定义为切片

例子:

定义一个结构

message User{
	string username=1;
	int32 age=2;  
	optional string password=3;  // 生成的是指针
	repeated string address=4;  // 生产的是切片
}

生成一下执行protoc --go_out=./ .\user.proto

生成下面的文件

type User struct {
    state protoimpl.MessageState
    sizeCache protoimpl.SizeCache
    unknownFields protoimpl.UnknownFields
    
    Username string `protobuf:"bytes,1,opt,name=username,proto3" json:"username,omitempty"`
    Age int32 `prtobuf:"varint,2,opt,name=age,proto3" json:"age,omitempty"`
    Password *string `protobuf:"bytes,3,opt,name=password,proto3,oneof" json:"password,omiyempty"`
    Address []string `protobuf:"bytes,4,rep,name=address,proto3" json:"address,omitempty"`
}

可以看到Address变成了一个切片

三、字段映射

.proto TypeNotesC++ TypePython TypeGo Type
doubledoublefloatfloat64
floatfloatfloatfloat32
int32使用变长编码,对于负值的效率很低,如果你的域有 可能有负值,请使用sint64替代int32intint32
uint32使用变长编码uint32int/longuint32
uint64使用变长编码uint64int/longuint64
sint32使用变长编码,这些编码在负值时比int32高效的多int32intint32
sint64使用变长编码,有符号的整型值。编码时比通常的 int64高效。int64int/longint64
fixed32总是4个字节,如果数值总是比总是比228大的话,这 个类型会比uint32高效。uint32intuint32
fixed64总是8个字节,如果数值总是比总是比256大的话,这 个类型会比uint64高效。uint64int/longuint64
sfixed32总是4个字节int32intint32
sfixed32总是4个字节int32intint32
sfixed64总是8个字节int64int/longint64
boolboolboolbool
string一个字符串必须是UTF-8编码或者7-bit ASCII编码的文 本。stringstr/unicodestring
bytes可能包含任意顺序的字节数据。stringstr[]byte

四、默认值

protobuf3删除了protobuf2中用来设置默认值的default关键字,取而代之的是protobuf3为各类型定义的默认值,也就是约定的默认值,如下表:

类型默认值
boolflase
整型0
string空字符串""
枚举enum第一个枚举元素的值,因为Protobuf3强制要求第一个枚举元素的值必须是0,所以枚举的默认值就是0
message不是null,而是DEFAULT_INSTANCE

五、标识号

标识号:在消息体的定义中,每个字段都必须要有一个唯一的标识号,标识号是[0.2^29-1]范围内的一个整数。

message User{
	string username=1;  // 位置1
	int32 age=2;
	optional string password=3;
	repeated string address=4;  // 位置4
}

以Person为例,name=1,id=2,email=3,phones=4中的1- 4就是标识号

六、定义多个消息队列

一个proto文件中可以定义多个消息类型

message UserRequest{
	string username=1;   // 位置1
	int32 age=2;
	optional string password=3;
	repeated string address=4;  // 位置4
}
message UserResponse{
	string username=1;
	int32 age=2;
	optional string password=3;
	repeated string address=4;
}

七、嵌套消息

可以在其他消息类型中定义,使用消息类型,在下面的例子中,Person消息就定义在PersonInfo消息内

message PersonInfo{
	message Person{
		string name=1;
		int32 height=2;
		repeated int32 weight=3;
	}
	repeated Person info=1;
}

如果你想在它的父消息类型的外部重用这个消息类型,你需要以PersonInfo.Person的形式来使用它,如:

message PersonMessage{
	PersonInfo.Person info=1;
}

当然也可以消息嵌套多层,比如

message Grandpa {
	message Father {
		message Son{
			string name=1;
			int32 age=2;
		}
	}
	message Uncle{
		message Son{
			string name=1;
			int32 age=1;
		}
	}
}

八、定义服务

如果想要将消息类型用在rpc系统中,可以在.proto文件中定义一个rpc服务接口,protocolbuffer编译器会根据所选择的不同语言生成服务接口代码及存根。

service SearchService{
	// rpc 服务的函数名(传入参数)返回(返回参数)
    rpc Search(UserRequest) returns(UserResponse);
}

上述代表表示,定义了一个RPC服务,该方法接收SearchRequest返回SearchResponse

参考:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值