我可以用下面的指令得到Protobuf枚举的字符串值:
str := testPB.Status_ENABLED.String()
如何执行逆操作?(从字符串中获取枚举元素)。
bgibtngc1#
生成的代码有一个名为map[string]int32的Map,类型为map[string]int32。然后,您可以将数值转换为实际定义的类型:
map[string]int32
num := testPB.Status_value[str] v := testPB.Status(num)
考虑到如果str值不存在于Map中(注意它是区分大小写的),Map查找将返回0。根据您如何定义protobuffer,0值可能被Map到一个没有“零”语义的枚举示例。这就是为什么建议将0Map到一个“未知”示例:
str
0
enum Status { UNKNOWN = 0; ENABLED = 1; // and so on }
在Go语言中,如果字符串的表示形式实际上是未知的,那么下面哪一种方法可以正确地产生一个临时的零值:
v := testPB.Status(testPB.Status_value["does_not_exist"]) fmt.Println(v == testPB.Status_UNKNOWN) // true
1.18开始使用泛型,可以编写可重用的代码来从字符串值构造protobuffer枚举:
func Enum[T ~string, PB ~int32](val T, pbmap map[string]int32, dft PB) PB { v, ok := pbmap[string(val)] if !ok { return dft } return PB(v) }
其中:
T
type MyEnum string
pbmap
<EnumName>_value
PB
上面的函数采用PB类型的默认值(显然),以便在字符串表示无效的情况下进行回退,并且还允许对PB进行类型推断,否则PB只能用作返回类型。用法:
type SomeEnum string const ( SomeEnumFoo SomeEnum = "FOO" SomeEnumBar SomeEnum = "BAR" ) func main() { foo := SomeEnumFoo v := Enum(foo, pb.SomeEnum_value, pb.SomeEnum_Foo) // ^ T ^ map[string]int32 ^ default PB value // v is type pb.SomeEnum }
1条答案
按热度按时间bgibtngc1#
生成的代码有一个名为
map[string]int32
的Map,类型为map[string]int32
。然后,您可以将数值转换为实际定义的类型:考虑到如果
str
值不存在于Map中(注意它是区分大小写的),Map查找将返回0
。根据您如何定义protobuffer,0
值可能被Map到一个没有“零”语义的枚举示例。这就是为什么建议将0
Map到一个“未知”示例:在Go语言中,如果字符串的表示形式实际上是未知的,那么下面哪一种方法可以正确地产生一个临时的零值:
1.18开始
使用泛型,可以编写可重用的代码来从字符串值构造protobuffer枚举:
其中:
T
是字符串表示,它也可以是具有底层类型字符串的类型,例如type MyEnum string
pbmap
是来自生成的protobuffer代码的<EnumName>_value
PB
是协议缓冲器枚举类型。上面的函数采用
PB
类型的默认值(显然),以便在字符串表示无效的情况下进行回退,并且还允许对PB
进行类型推断,否则PB
只能用作返回类型。用法: