go - 如何使用 golang 设置 protobuf2 枚举
问题描述
我正在尝试在 golang 中使用 protobuf2 枚举,但我无法弄清楚。
我创建了一个简单的 protobuf 文件:
syntax = "proto2" ;
package enum ;
message Foo{
enum Bar{
LOL = 1;
}
optional Bar baz = 1;
}
我创建了一个简单的 golang 文件:
package main
import (
enum "./enum"
"github.com/golang/protobuf/proto"
)
func main() {
msg := &enum.Foo{
Baz: enum.Foo_LOL,
}
proto.Marshal(&msg)
}
我有一个错误。
./foo.go:10: cannot use enum.Foo_LOL (type enum.Foo_Bar) as type *enum.Foo_Bar in field value
解决起来似乎很简单,只需&
在enum.Foo_Bar
.
package main
import (
enum "./enum"
"github.com/golang/protobuf/proto"
)
func main() {
msg := &enum.Foo{
Baz: &enum.Foo_LOL,
}
proto.Marshal(&msg)
}
没有:
./foo.go:10: cannot take the address of enum.Foo_LOL
我搜索了谷歌,发现这个人被机器人控制了。他有一些工作代码,但它的冗长足以让一位圣经学者感到厌烦:
package main
import (
enum "./enum"
"github.com/golang/protobuf/proto"
)
var lolVar = enum.Foo_LOL
func main() {
msg := &enum.Foo{
Baz: &lolVar,
}
proto.Marshal(msg)
}
我查看了生成的代码并找到了一个Enum
方法,该方法也有效,但冗长到足以让税务审计员感到厌烦:
package main
import (
enum "./enum"
"github.com/golang/protobuf/proto"
)
func main() {
msg := &enum.Foo{
Baz: enum.Foo_LOL.Enum(),
}
proto.Marshal(msg)
}
预期的方法是什么?
解决方案
Protobufsyntax="proto2"
生成具有指针类型的枚举字段,因此Foo.baz
类型为*Foo_Bar
. 您不能为该Foo_Bar
字段分配非指针值,只能分配指针值。
此外,您在 protobuf 文件中列出的枚举值将生成为 Go 中的常量。并且不能取常量值的地址,详见:Find address of constant in go
如果您的 protobuf 生成一个Enum()
返回指向该值的指针的方法,那很好,您可以使用它。但是这个方法并不总是生成的,所以如果你没有找到某个类型/枚举的这个方法,请不要感到惊讶。
如果它丢失,最简单的方法是创建一个(本地)变量,您可以获取其地址:
lol := enum.Foo_LOL
msg := &enum.Foo{
Baz: &lol,
}
err := proto.Marshal(msg)
如果您必须多次/多次执行此操作,请创建一个辅助函数来满足该Enum()
方法的目的。这是您如何创建一个:
func barPtr(b enum.Foo_Bar) *enum.Foo_Bar { return &b }
并使用它:
msg := &enum.Foo{
Baz: barPtr(enum.Foo_LOL),
}
err := proto.Marshal(msg)
还有许多其他选项可以获取指向整数类型的指针,但它们不一定更简洁或更高效。您可以在此处查看不同方法的列表:How do I do a literal *int64 in Go?
推荐阅读
- swift - 滚动教程时填充 UIPage 控件的点
- nsview - 使用 XCode 在 MacOS 应用程序中放置在 NSScrollView 内的 NSView 不显示滚动条
- json - 在颤动中发送带有json正文的GET请求
- javascript - 按 className 滚动到作为元素子项的子项的段落的视图 - 纯 JS
- python - 根据列值的计数过滤 CSV 行
- colors - 在地图地理熊猫的色标中设置起点
- apache-kafka - Kafka Streams:什么时候调用 StateRestoreListener?
- python - TypeVar('T') 和 Any 之间的区别
- node.js - 带有 Typescript 错误的玩笑:超时 - 在 jest.setTimeout.Timeout 指定的 5000 毫秒超时内未调用异步回调
- python - 无法在 pycharm 中安装 xml.etree.elementtree