如何在golang中使用protobuf.any

问题描述 投票:0回答:5

我在我的 go 项目中使用 grpc。下面是代码:

示例.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)
}

但我不知道如何处理详细信息(接口{})字段。我知道我可以使用任何类型的接口,但不确定如何在这里使用它。有人可以帮忙吗?谢谢

go protocol-buffers
5个回答
11
投票

由于 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
}


10
投票

protobuf/ptypes 包具有用于将任意原始消息转换为任意原型消息或从任意原型消息转换为任意原型消息的实用程序:


元帅Any

func MarshalAny(m proto.Message) (*anypb.Any, error)

MarshalAny 将给定的消息 m 编组为 anypb.Any 消息。


UnmarshalAny

func UnmarshalAny(any *anypb.Any, m proto.Message) error

UnmarshalAny 将anypb.Any 消息中包含的编码值解组到提供的消息m 中。如果目标消息与 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)
}

3
投票
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 函数


0
投票
func ConvertInterfaceToAny(v interface{}) (*any.Any, error) {
 anyValue := &any.Any{}
 bytes, _ := json.Marshal(v)
 bytesValue := &wrappers.BytesValue{
    Value: bytes,
 }
 err := anypb.MarshalFrom(anyValue, bytesValue, proto.MarshalOptions{})
 return anyValue, err

}


-1
投票
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;
}
© www.soinside.com 2019 - 2024. All rights reserved.