我在 proto 文件中有一个枚举,它在 pb.go 文件中生成整数常量。我现在有一些来自外部数据源的整数,并希望将它们安全地映射到可能的常量。
这是我目前拥有的:https://play.golang.org/p/-5VZqPbukd
package main
import (
"errors"
"fmt"
)
//enum in the proto file
//
// enum X {
// A = 0;
// B = 1;
// C = 2;
// D = 3;
// }
//enum type generated by protoc
type X int32
//enum constants generated by protoc
const (
X_A X = 0
X_B X = 1
X_C X = 2
X_D X = 3
)
func intToX(v int) (X, error) {
x := X(v)
switch x {
case X_A, X_B, X_C, X_D:
return x, nil
}
return 0, errors.New("could not convert int to X")
}
func main() {
for i := -1; i < 10; i++ {
if x, err := intToX(i); err != nil {
fmt.Println("unhandled error:", err, "for input value", i)
} else {
fmt.Printf("%d => X(%d)\n", i, x)
}
}
}
问题:是否有更好、更惯用的方法将传入的整数值映射到协议(protocol)生成的常量?
特别是,我想避免在 case A, B, C, D
语句中显式列出所有常量。
最佳答案
我不知道您使用的是哪个原型(prototype)生成包,但是使用 github.com/golang/protobuf/proto
您还可以获得枚举的反向映射。
示例 xyz.pb.go 生成的文件:
type TimeInterval int32
const (
TimeInterval_TI_UNKNOWN TimeInterval = 0
TimeInterval_TI_HOUR TimeInterval = 1
TimeInterval_TI_DAY TimeInterval = 2
TimeInterval_TI_WEEK TimeInterval = 3
TimeInterval_TI_MONTH TimeInterval = 4
TimeInterval_TI_QUARTER TimeInterval = 5
TimeInterval_TI_YEAR TimeInterval = 6
)
var TimeInterval_name = map[int32]string{
0: "TI_UNKNOWN",
1: "TI_HOUR",
2: "TI_DAY",
3: "TI_WEEK",
4: "TI_MONTH",
5: "TI_QUARTER",
6: "TI_YEAR",
}
var TimeInterval_value = map[string]int32{
"TI_UNKNOWN": 0,
"TI_HOUR": 1,
"TI_DAY": 2,
"TI_WEEK": 3,
"TI_MONTH": 4,
"TI_QUARTER": 5,
"TI_YEAR": 6,
}
func (x TimeInterval) String() string {
return proto.EnumName(TimeInterval_name, int32(x))
}
func (TimeInterval) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
因此,您可以通过以下方式测试是否存在:
if _, found := TimeInterval_name[testinputint]; found{
//all ok
} else {
//not a value for this enum
}
关于Go:安全地将整数转换为 Protocol Buffer 枚举值的最佳实践,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38957169/