wangming1993 / issues

记录学习中的一些问题,体会与心得 https://wangming1993.github.io/issues
8 stars 4 forks source link

proto buffer中enum类型在go中的实现 #39

Open wangming1993 opened 7 years ago

wangming1993 commented 7 years ago

_enum_在proto buffer是一种类型,但并不是go支持的内置类型,protoc-gen-go为了实现enum的支持,采用的是两组map的实现方式。

如下:

message Person {
  string name = 1;
  int32 id = 2;  // Unique ID number for this person.
  string email = 3;

  enum PhoneType {
    MOBILE = 0;
    home = 1;
    work = 2;
  }
  PhoneType type = 4;
}

Person中有一个字段type, 其类型为 PhoneType的enum类型,在使用protoc生成go代码时, protoc --go_out=plugins=grpc:. enum.proto, 会有如下转换:


type Person_PhoneType int32

const (
    Person_MOBILE Person_PhoneType = 0
    Person_home   Person_PhoneType = 1
    Person_work   Person_PhoneType = 2
)

var Person_PhoneType_name = map[int32]string{
    0: "MOBILE",
    1: "home",
    2: "work",
}
var Person_PhoneType_value = map[string]int32{
    "MOBILE": 0,
    "home":   1,
    "work":   2,
}

func (x Person_PhoneType) String() string {
    return proto.EnumName(Person_PhoneType_name, int32(x))
}

可以看到,定义enum类型时字段的大小写会被保留作为值, 在使用时:

&pb.Person{
        Name:  "mike",
    Email: "wangming@163.com",
    Type:  pb.Person_MOBILE,
}

// 或者通过字符串转化为Person_PhoneType类型
var ht pb.Person_PhoneType
key, ok := pb.Person_PhoneType_value[stringValue]
if !ok {
    panic("not support enum type")
}
ht = pb.Person_PhoneType(key)

// 如果拿到了Person_PhoneType类型的值,想以字符串的形式输出,则可以
ht.String()

这么想想,真是麻烦啊 <!>