gpt4 book ai didi

go - proto.MessageName 返回空字符串

转载 作者:IT王子 更新时间:2023-10-29 02:22:46 27 4
gpt4 key购买 nike

我完全陷入了 Go 中 Protobuf 的问题

给定以下代码:

if proto.MessageName(&messages.AddedItemEvent{}) == "" {
log.Fatal("empty")
}

这将评估为 true 并退出应用程序。什么可能使 protobuf 在 MessageName 上返回空字符串?我可以看到类型及其名称在生成的 protobuf 消息代码中按应有的方式注册:

func init() {
proto.RegisterType((*AddItemCommand)(nil), "messages.AddItemCommand")
proto.RegisterType((*AddedItemEvent)(nil), "messages.AddedItemEvent")
proto.RegisterType((*RenameCommand)(nil), "messages.RenameCommand")
proto.RegisterType((*RenamedEvent)(nil), "messages.RenamedEvent")
proto.RegisterType((*DumpCommand)(nil), "messages.DumpCommand")
}

我还验证了上面的 init 确实在运行,而且确实如此。

我还有其他生成的原型(prototype)消息,它们会按预期返回它们的名称。那么这里出了什么问题?

编辑原型(prototype)文件看起来像这样

syntax = "proto3";
package messages;

//user messages
message AddItemCommand {
string item = 1;
}
message AddedItemEvent {
string item = 1;
}
message RenameCommand {
string name = 1;
}
message RenamedEvent {
string name = 1;
}
message DumpCommand {}

再次编辑。手动调用 proto.RegisterType((*messages.AddedItemEvent)(nil), "messages.AddedItemEvent")

main 函数,让它工作。因此,不知何故,类型注册表在 messages.initmain

之间的某处被清除

有人吗?

最佳答案

不,类型注册表未清除。

很可能您在生成的代码中使用了 proto 包的不同实现,其中 proto 包实现选择由您选择的 proto 代码生成器解决。在您的代码中,您实际上是在尝试获取 MessageName

Go 中的每个导入包在 go 二进制进程生命周期内都被初始化一次。每个初始化包都有自己的名称表(导出的和未导出的)及其对应的值。 proto 包特别维护已知原型(prototype)消息名称和类型的所谓“注册表”。稍微简化一下,registry 是一个包范围的映射,将消息类型与其相应的名称相关联。此 map 在包初始化时初始化和填充。然后,要检索 MessageName,您可以通过一些辅助函数间接访问它。关键是,如果您在代码、生成的代码或依赖项中使用不同的 proto 包实现,那么很可能在应用程序启动时填充一个注册表,然后,您正在尝试从其他对此一无所知的注册表中检索 MessageName。经验法则是在整个应用中始终使用单一 vendor 提供的 protoc 代码生成器插件、预生成的原型(prototype)类型库和 proto 包实现。

最流行的 proto 包(我从未使用或遇到过任何其他包)是 https://github.com/golang/protobufhttps://github.com/gogo/protobuf .仔细检查您的协议(protocol)生成器插件和包导入,我希望一切都好。

关于go - proto.MessageName 返回空字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39712915/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com