背景
protobuf 2中定义的enum枚举值必须为数字类型,故不支持string类型,但有些业务场景又确实需要定义string常量。
目标
在protobuf 2中定义string常量。
方案
思路:通optional + default实现string常量。
细节:
1、protobuf定义
syntax = "proto2";
package stonelu.learn.pb;message Constant {message TestStringConst {optional string NO_TEST_STRING_CONST = 1 [default = "no_test_string_const"]; // val: no_test_string_constoptional string Email = 2 [default = "email"]; // val: emailoptional string Sex = 3 [default = "sex"]; // val: sexoptional string Address = 4 [default = "address"]; // val address}
}
2、生成pb.go文件(文件名后缀由生成语言决定,此处以go为例)
指令不在此赘述。
生成的文件关键信息如下(注意中文注释部分):
type Constant_TestStringConst struct {NO_TEST_STRING_CONST *string `protobuf:"bytes,1,opt,name=NO_TEST_STRING_CONST,json=NOTESTSTRINGCONST,def=no_test_string_const" json:"NO_TEST_STRING_CONST"`Email *string `protobuf:"bytes,2,opt,name=Email,def=email" json:"Email"`Sex *string `protobuf:"bytes,3,opt,name=Sex,def=sex" json:"Sex"`Address *string `protobuf:"bytes,4,opt,name=Address,def=address" json:"Address"`XXX_unrecognized []byte `json:"-"`
}func (m *Constant_TestStringConst) Reset() { *m = Constant_TestStringConst{} }
func (m *Constant_TestStringConst) String() string { return proto.CompactTextString(m) }
func (*Constant_TestStringConst) ProtoMessage() {}
func (*Constant_TestStringConst) Descriptor() ([]byte, []int) {return fileDescriptorSellerCsRouting, []int{0, 2}
}const Default_Constant_TestStringConst_NO_TEST_STRING_CONST string = "no_test_string_const"
const Default_Constant_TestStringConst_Email string = "email"
const Default_Constant_TestStringConst_Sex string = "sex"
const Default_Constant_TestStringConst_Address string = "address"func (m *Constant_TestStringConst) GetNO_TEST_STRING_CONST() string {if m != nil && m.NO_TEST_STRING_CONST != nil {return *m.NO_TEST_STRING_CONST}return Default_Constant_TestStringConst_NO_TEST_STRING_CONST
}func (m *Constant_TestStringConst) GetEmail() string {// 【核心代码】// 如果email字段有值,则返回,但其实一般不会对其做赋值if m != nil && m.Email != nil {return *m.Email}// 一般都走下面这里:返回默认值:"email"// sex、address字段类同,后面不再赘述return Default_Constant_TestStringConst_Email
}func (m *Constant_TestStringConst) GetSex() string {if m != nil && m.Sex != nil {return *m.Sex}return Default_Constant_TestStringConst_Sex
}func (m *Constant_TestStringConst) GetAddress() string {if m != nil && m.Address != nil {return *m.Address}return Default_Constant_TestStringConst_Address
}
3、使用
v := (&stonelu_learn_pb.Constant_TestStringConst{}).GetEmail()t.Logf("v: %v", v)