首先,您应该了解DB列中存储的内容.json.RawMessage
被简单地定义为type RawMessage []byte
(见the doc).而且它没有提供足够的信息来回答你的问题.
我将提供一个演示来展示google.protobuf.Any
是如何工作的,这将帮助您更好地理解您的问题.
Notes:
- Any is for embedding other types in a message. So I define two other messages (
Foo
and Bar
) in the demo.
Any
消息类型允许您将消息用作嵌入类型,而无需.proto定义.Any包含作为字节的任意序列化消息,以及充当该消息类型的全局唯一标识符并解析为该消息类型的URL.
- 实际上,您的问题取决于数据库中存储的内容.请参阅
main.go
中的 comments .
演示的文件夹 struct :
├── go.mod
├── main.go
└── pb
├── demo.pb.go
└── demo.proto
go.mod
:
module github.com/ZekeLu/demo
go 1.19
require (
github.com/golang/protobuf v1.5.2
google.golang.org/protobuf v1.28.1
)
pb/demo.proto
:
syntax = "proto3";
package pb;
import "google/protobuf/any.proto";
option go_package = "github.com/ZekeLu/demo/pb";
message MyMessage {
repeated google.protobuf.Any list = 1;
}
message Foo {
int32 v = 1;
}
message Bar {
string v = 1;
}
main.go
:
package main
import (
"encoding/json"
"fmt"
"google.golang.org/protobuf/types/known/anypb"
"github.com/ZekeLu/demo/pb"
)
func main() {
// If the db stores an instance of pb.Foo, then unmarshal it first.
buf := json.RawMessage([]byte(`{"v":10}`))
var foo pb.Foo
err := json.Unmarshal(buf, &foo)
if err != nil {
panic(err)
}
// And then marshal it into a new Any instance, which can be used to
// create a slice that can be assigned to pb.MyMessage.List.
a1, err := anypb.New(&foo)
if err != nil {
panic(err)
}
bar := &pb.Bar{V: "10"}
a2, err := anypb.New(bar)
if err != nil {
panic(err)
}
// Initialize the List field.
m := pb.MyMessage{List: []*anypb.Any{a1, a2}}
buf, err = json.Marshal(&m)
if err != nil {
panic(err)
}
fmt.Printf("%s\n", buf)
// Output: {"list":[{"type_url":"type.googleapis.com/pb.Foo","value":"CAo="},{"type_url":"type.googleapis.com/pb.Bar","value":"CgIxMA=="}]}
// If the db stores the output above, it can be unmarshal directly
var m2 pb.MyMessage
err = json.Unmarshal(buf, &m2)
if err != nil {
panic(err)
}
fmt.Printf("%v\n", m2.List)
// Output: [[type.googleapis.com/pb.Foo]:{v:10} [type.googleapis.com/pb.Bar]:{v:"10"}]
}
运行演示的步骤:
$ protoc --proto_path=pb --go_out=pb --go_opt=paths=source_relative demo.proto
$ go mod tidy
$ go run main.go