2 回答
TA贡献1772条经验 获得超5个赞
如您所知,是消息类型,因此当您没有为其设置任何值时,它将为零。google.protobuf.Any
您必须使用您的结构取消封送数据,请参阅下面来自 protobuf 示例的代码
// marshal any
foo := &pb.Foo{...}
any, err := anypb.New(foo)
if err != nil {
...
}
// unmarshal any
foo := &pb.Foo{}
if err := any.UnmarshalTo(foo); err != nil {
...
}
或者我认为你可以用它与指针接口(&接口{})一起使用,如下所示:
d := &interface{}{}
if err := endorsement.Data.UnmarshalTo(d); err != nil {
...
}
TA贡献1818条经验 获得超7个赞
从软件包1 文档取消编组任何:
UnmarshalNew
使用全局类型注册表解析消息类型,并构造该消息的新实例以取消编组。为了使消息类型显示在全局注册表中,必须将表示该 protobuf 消息类型的 Go 类型链接到 Go 二进制文件中。对于由原始生成生成的消息,这是通过导入表示 .proto 文件的生成的 Go 包来实现的。
注册表的类型为 。类型查找是使用字段完成的,该字段在封送原始消息时由 gRPC 客户端设置为具体类型的 url。protoregistry.GlobalTypes
Any.TypeUrl
令人困惑的细节是,它可以是任何原始缓冲区消息,但该原始缓冲区消息必须在某个地方定义。Any
您的文件没有与输入中的对象匹配的消息定义。可能是此消息在其他地方定义(不在您自己的原型文件中),但无论如何,您都必须导入生成的消息所在的Go包。.proto
data
Data
否则,如果输入不是来自已定义的原型消息,您可以自己向原型添加消息定义,然后使用 UnmarshalTo
:
// proto file
message Data {
string type = 1;
int user_id = 2;
Transaction transaction = 3;
}
message Transaction {
float amount = 1;
}
然后:
for _, endorsement := range txnPayload.Endorsements {
data := generated.Data{}
err := endorsement.Data.UnmarshalTo(&data)
if err != nil {
log.Print("Error while unmarshaling the endorsement")
}
}
如果您只需要任意的字节序列,即真正未知的类型,请使用原型类型并将其视为 JSON 有效负载。bytes
将其建模为 Go 结构:
type Data struct {
Type string `json:"type"`
UserID int `json:"userId"`
Transaction struct{
Amount float64 `json:"amount"`
} `json:"transaction"`
}
或者,如果客户可以发送任何东西。map[string]interface{}
然后在您的处理程序功能中:
for _, endorsement := range txnPayload.Endorsements {
data := Data{} // or `map[string]interface{}`
err := json.Unmarshal(endorsement.Data, &data)
if err != nil {
log.Print("Error while unmarshaling the endorsement")
}
}
- 2 回答
- 0 关注
- 152 浏览
添加回答
举报