亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

Protobuf.Any - 從 json.RawMessage 解組

Protobuf.Any - 從 json.RawMessage 解組

Go
千萬里不及你 2023-03-15 14:49:17
我有來自數據庫的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有什么辦法可以做到這一點?
查看完整描述

1 回答

?
莫回無

TA貢獻1865條經驗 獲得超7個贊

首先,您應該了解 DB 列中存儲的內容。json.RawMessage被簡單地定義為type RawMessage []byte。而且它沒有攜帶足夠的信息來回答你的問題。

我將提供一個演示來展示它是如何google.protobuf.Any工作的,這應該可以幫助您更好地理解您的問題。

注意事項

  1. Any用于在消息中嵌入其他類型。所以我在演示中?定義了另外兩個消息(Foo和)。Bar

    消息Any類型允許您將消息用作嵌入式類型而無需其 .proto 定義。Any 包含作為字節的任意序列化消息,以及充當該消息類型的全局唯一標識符并解析為該消息類型的 URL。

  2. 實際上,您的問題取決于數據庫中存儲的內容。請參閱 中的評論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


查看完整回答
反對 回復 2023-03-15
  • 1 回答
  • 0 關注
  • 244 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號