我有來自資料庫的json.RawMessage格式資料。具體的列是jsonb。
我真的找不到一種方法將資料解組到 proto 上定義為 protobuf.Any 的屬性,就像這樣。
repeated google.protobuf.Any list = 1;
當我嘗試使用json.Unmarshal()then解組資料庫中的資料時,它list是空的。檔案提到了這樣的事情:
foo := &pb.Foo{...}
any, err := anypb.New(foo)
if err != nil {
...
}
...
foo := &pb.Foo{}
if err := any.UnmarshalTo(foo); err != nil {
...
}
但在這個例子中是我無法轉換foo的型別,因為我有.proto.Messagejson.RawMessage
有什么辦法可以做到這一點?
uj5u.com熱心網友回復:
首先,您應該了解 DB 列中存盤的內容。json.RawMessage被簡單地定義為type RawMessage []byte(參見檔案)。而且它沒有攜帶足夠的資訊來回答你的問題。
我將提供一個演示來展示它是如何google.protobuf.Any作業的,這應該可以幫助您更好地理解您的問題。
注意事項:
- Any用于在訊息中嵌入其他型別。所以我在演示中
定義了另外兩個訊息(
Foo和)。Bar訊息型別允許您將
Any訊息用作嵌入式型別而無需其 .proto 定義。Any 包含作為位元組的任意序列化訊息,以及充當該訊息型別的全域唯一識別符號并決議為該訊息型別的 URL。 - 實際上,您的問題取決于資料庫中存盤的內容。請參閱 中的評論
main.go。
演示的檔案夾結構:
├── 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
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/535743.html
標籤:去protobuf-go
