这里使用一个测试文件对照说明常用结构的protobuf到golang的转换。只说明关键部分代码,详细内容请查看完整文件。示例文件在proto/test目录下。
1.1.1. Package
在proto文件中使用package关键字声明包名,默认转换成go中的包名与此一致,如果需要指定不一样的包名,可以使用go_package选项:
package test;option go_package="test";
1.1.2. Message
proto中的message对应go中的struct,全部使用驼峰命名规则。嵌套定义的message,enum转换为go之后,名称变为Parent_Child结构。
示例proto:
// Test 测试message Test {int32 age = 1;int64 count = 2;double money = 3;float score = 4;string name = 5;bool fat = 6;bytes char = 7;// Status 枚举状态enum Status {OK = 0;FAIL = 1;}Status status = 8;// Child 子结构message Child {string sex = 1;}Child child = 9;map<string, string> dict = 10;}
转换结果:
// Status 枚举状态type Test_Status int32const (Test_OK Test_Status = 0Test_FAIL Test_Status = 1)// Test 测试type Test struct {Age int32 `protobuf:"varint,1,opt,name=age" json:"age,omitempty"`Count int64 `protobuf:"varint,2,opt,name=count" json:"count,omitempty"`Money float64 `protobuf:"fixed64,3,opt,name=money" json:"money,omitempty"`Score float32 `protobuf:"fixed32,4,opt,name=score" json:"score,omitempty"`Name string `protobuf:"bytes,5,opt,name=name" json:"name,omitempty"`Fat bool `protobuf:"varint,6,opt,name=fat" json:"fat,omitempty"`Char []byte `protobuf:"bytes,7,opt,name=char,proto3" json:"char,omitempty"`Status Test_Status `protobuf:"varint,8,opt,name=status,enum=test.Test_Status" json:"status,omitempty"`Child *Test_Child `protobuf:"bytes,9,opt,name=child" json:"child,omitempty"`Dict map[string]string `protobuf:"bytes,10,rep,name=dict" json:"dict,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`}// Child 子结构type Test_Child struct {Sex string `protobuf:"bytes,1,opt,name=sex" json:"sex,omitempty"`}
除了会生成对应的结构外,还会有些工具方法,如字段的getter:
func (m *Test) GetAge() int32 {if m != nil {return m.Age}return 0}//枚举类型会生成对应名称的常量,同时会有两个map方便使用:var Test_Status_name = map[int32]string{0: "OK",1: "FAIL",}var Test_Status_value = map[string]int32{"OK": 0,"FAIL": 1,}
1.1.3. Service
定义一个简单的Service,TestService有一个方法Test,接收一个Request参数,返回Response:
// TestService 测试服务service TestService {// Test 测试方法rpc Test(Request) returns (Response) {};}// Request 请求结构message Request {string name = 1;}// Response 响应结构message Response {string message = 1;}// ============ 转换结果:// 客户端接口type TestServiceClient interface {// Test 测试方法Test(ctx context.Context, in *Request, opts ...grpc.CallOption) (*Response, error)}// 服务端接口type TestServiceServer interface {// Test 测试方法Test(context.Context, *Request) (*Response, error)}
生成的go代码中包含该Service定义的接口,客户端接口已经自动实现了,直接供客户端使用者调用,服务端接口需要由服务提供方实现。
