如何在 golang 中使用 protobuf.any
how to use protobuf.any in golang
我在我的 go 项目中使用 grpc。下面是代码:
example.proto:
syntax = "proto3";
message Example {
string message = 1;
google.protobuf.Any details = 2;
}
main.go
func logMessage (m string, d interface{}) {
message := & example.message{
message: m,
details: ??
}
log(&message)
}
但我不确定如何处理 details(interface{}) 字段。我知道我可以使用任何类型的接口,但不确定如何在这里使用它。任何人都可以帮忙吗?谢谢
protobuf/ptypes 包具有将 to/from 任意原始消息转换为任何的实用程序:
func MarshalAny(m proto.Message) (*anypb.Any, error)
MarshalAny 将给定的消息 m 编组为 anypb.Any 消息。
func UnmarshalAny(any *anypb.Any, m proto.Message) error
UnmarshalAny 将 anypb.Any 消息中包含的编码值解组到提供的消息 m 中。 returns 如果目标消息与 Any 消息中的类型不匹配或发生解组错误,则会出错。
在您的示例中,您将使用以下内容:
func logMessage (m string, d proto.Message) {
details, err := ptypes.MarshalAny(d)
if err != nil {
panic(err)
}
message := & example.message{
message: m,
details: details
}
log(&message)
}
由于 protobuf/ptypes 已弃用,因此值得使用 anypb.UnmarshalTo
import (
"google.golang.org/protobuf/types/known/anypb"
"github.com/golang/protobuf/ptypes/any"
)
func Unmarshal(data *any.Any) (*YourMessage, err) {
var m YourMessage
err := anypb.UnmarshalTo(data, &m, proto.UnmarshalOptions{})
return &m,err
}
func pbany(v interface{}) (*anypb.Any, error) {
pv, ok := v.(proto.Message)
if !ok {
return &anypb.Any{}, fmt.Errorf("%v is not proto.Message", pv)
}
return anypb.New(pv)
使用 anypb.New
api,在您的代码中,将 d
传递给 pbany 函数
func interfaceToAny(v interface{}) (*anypb.Any, error) {
bytes, err := json.Marshal(v)
if err != nil {
println("error json.Marshal interfaceToAny")
return nil, err
}
m := api.Bytes{B: bytes}
return anypb.New(&m)
}
message Bytes {
bytes b = 1;
}
我在我的 go 项目中使用 grpc。下面是代码:
example.proto:
syntax = "proto3";
message Example {
string message = 1;
google.protobuf.Any details = 2;
}
main.go
func logMessage (m string, d interface{}) {
message := & example.message{
message: m,
details: ??
}
log(&message)
}
但我不确定如何处理 details(interface{}) 字段。我知道我可以使用任何类型的接口,但不确定如何在这里使用它。任何人都可以帮忙吗?谢谢
protobuf/ptypes 包具有将 to/from 任意原始消息转换为任何的实用程序:
func MarshalAny(m proto.Message) (*anypb.Any, error)
MarshalAny 将给定的消息 m 编组为 anypb.Any 消息。
func UnmarshalAny(any *anypb.Any, m proto.Message) error
UnmarshalAny 将 anypb.Any 消息中包含的编码值解组到提供的消息 m 中。 returns 如果目标消息与 Any 消息中的类型不匹配或发生解组错误,则会出错。
在您的示例中,您将使用以下内容:
func logMessage (m string, d proto.Message) {
details, err := ptypes.MarshalAny(d)
if err != nil {
panic(err)
}
message := & example.message{
message: m,
details: details
}
log(&message)
}
由于 protobuf/ptypes 已弃用,因此值得使用 anypb.UnmarshalTo
import (
"google.golang.org/protobuf/types/known/anypb"
"github.com/golang/protobuf/ptypes/any"
)
func Unmarshal(data *any.Any) (*YourMessage, err) {
var m YourMessage
err := anypb.UnmarshalTo(data, &m, proto.UnmarshalOptions{})
return &m,err
}
func pbany(v interface{}) (*anypb.Any, error) {
pv, ok := v.(proto.Message)
if !ok {
return &anypb.Any{}, fmt.Errorf("%v is not proto.Message", pv)
}
return anypb.New(pv)
使用 anypb.New
api,在您的代码中,将 d
传递给 pbany 函数
func interfaceToAny(v interface{}) (*anypb.Any, error) {
bytes, err := json.Marshal(v)
if err != nil {
println("error json.Marshal interfaceToAny")
return nil, err
}
m := api.Bytes{B: bytes}
return anypb.New(&m)
}
message Bytes {
bytes b = 1;
}