你可以使用类型切换(type switch)来确定 protoreflect.MessageDescriptor 的类型。

huangapple go评论80阅读模式
英文:

How do I use a type switch to determine the type of a protoreflect.MessageDescriptor?

问题

我正在使用protogen包编写一个生成协议的插件。

我正在循环遍历消息的字段,并希望确定一个字段是否属于几种不同的消息类型之一。

可以使用以下方式将消息类型的名称作为字符串获取:

field.Desc.Message().FullName() // mypackage.MyMessage

这种方法的问题在于,我需要根据一个字符串进行切换,这样容易出错:

switch field.Desc.Message().FullName(){
  case "mypackage.MyMessage":

  case "mypackage.MyMessage2":
}

有没有办法使用类型断言来实现这个?我尝试使用dynamicpb创建消息的实例,但类型断言不起作用:

mt := dynamicpb.NewMessage(field.Desc.Message())

msg, ok := mt.(*mypackage.MyMessage) // 尽管field.Desc.Message().FullName()返回mypackage.MyMessage,但ok为false
英文:

I am writing a protoc generation plugin using the protogen package.

I am looping the fields of a message and want to determine if a field is one of a few different message types.

It is possible to get the name of the message type as a string using:

field.Desc.Message().FullName() // mypackage.MyMessage

The problem with this approach is that I will need to switch against a string, which is error-prone:

switch field.Desc.Message().FullName(){
  case "mypackage.MyMessage":

  case "mypackage.MyMessage2":
}

Is there anyway to do this using a type assertion? I tried to create an instance of the message using dynamicpc, but the type assertion does not work:

mt := dynamicpb.NewMessage(field.Desc.Message())

msg, ok := mt.(*mypackage.MyMessage) // ok is false despite field.Desc.Message().FullName() returning mypackage.MyMessage

答案1

得分: 1

dynamicpb.NewMessage函数不会创建一个Golang结构体mypackage.MyMessage,而是创建一个与mypackage.MyMessage具有相同二进制形式的数据结构。

请查看Message数据结构的内部:

// 修改Message的操作不适用于并发使用。
type Message struct {
	typ     messageType
	known   map[protoreflect.FieldNumber]protoreflect.Value
	ext     map[protoreflect.FieldNumber]protoreflect.FieldDescriptor
	unknown protoreflect.RawFields
}

它只是一个存储字段值以及字段元数据的容器。

英文:

The function dynamicpb.NewMessage doesn't create a Golang structure mypackage.MyMessage. Instead it creates a data structure that marshals into the same binary form as mypackage.MyMessage

Have a look inside the Message data structure:

// Operations which modify a Message are not safe for concurrent use.
type Message struct {
	typ     messageType
	known   map[protoreflect.FieldNumber]protoreflect.Value
	ext     map[protoreflect.FieldNumber]protoreflect.FieldDescriptor
	unknown protoreflect.RawFields
}

It is just a storage for field values along with with fields' metadata.

huangapple
  • 本文由 发表于 2022年8月25日 15:04:12
  • 转载请务必保留本文链接:https://go.coder-hub.com/73483231.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定