簡體   English   中英

如何使用 protobuf 反射而不是 proto.GetProperties?

[英]how to use protobuf reflection instead of proto.GetProperties?

我在“github.com/golang/protobuf@v1.5.2/proto/properties.go”中使用 proto.GetProperties 來獲取原型消息的屬性。 但是 function “GetProperties” 已棄用:

Deprecated: Use protobuf reflection instead.

那么,如何使用 protobuf 反射而不是 proto.GetProperties?

是指使用“google.golang.org/protobuf/proto”中的東西嗎?

有樣品嗎?

我的環境:

golang : v1.17.5
github.com/golang/protobuf : v1.5.2
google.golang.org/protobuf : v1.28.1

經過一番研究,我解決了自己的問題。

樣本:

package reflect

import (
    "fmt"
    protoOld "github.com/golang/protobuf/proto"
    "github.com/zhaochuninhefei/myproto-go/owner"
    "google.golang.org/protobuf/proto"
    "reflect"
)

func doReflect() {
    owner1 := &owner.Owner{
        OwnerId: 1,
        OwnerName: "owner1",
        OwnerDesc: "just test",
    }
    fmt.Printf("owner1: %s\n", owner1)

    oldReflect(owner1)
    newReflect(owner1)
}

func oldReflect(msg protoOld.Message) {
    pmVal := reflect.ValueOf(msg)
    if pmVal.Kind() != reflect.Ptr {
        fmt.Println("error in oldReflect 1")
        return
    }
    if pmVal.IsNil() {
        fmt.Println("error in oldReflect 2")
        return
    }
    mVal := pmVal.Elem()
    if mVal.Kind() != reflect.Struct {
        fmt.Println("error in oldReflect 3")
        return
    }
    protoProps := protoOld.GetProperties(mVal.Type())
    fmt.Println("----- oldReflect:")
    for _, prop := range protoProps.Prop {
        fmt.Println(prop)
    }
}

func newReflect(msg proto.Message) {
    m := msg.ProtoReflect()
    fds := m.Descriptor().Fields()
    fmt.Println("----- newReflect:")
    for k := 0; k < fds.Len(); k++ {
        fd := fds.Get(k)
        fmt.Println(fd)
    }
}

oldReflect 中的“protoOld.GetProperties”已棄用。 我們可以在 newReflect 中使用“msg.ProtoReflect().Descriptor().Fields()”。

示例代碼(doReflect)的測試用例執行結果為:

/usr/golang/go_1.17.5/bin/go tool test2json -t /tmp/GoLand/___Test_doReflect_in_github_com_zhaochuninhefei_myproto_test_reflect.test -test.v -test.paniconexit0 -test.run ^\QTest_doReflect\E$
=== RUN   Test_doReflect
owner1: owner_id:1 owner_name:"owner1" owner_desc:"just test"
----- oldReflect:
,0,name=XXX_state
,0,name=XXX_sizeCache
,0,name=XXX_unknownFields
varint,1,opt,name=owner_id,json=ownerId,proto3
bytes,2,opt,name=owner_name,json=ownerName,proto3
bytes,16,opt,name=owner_desc,json=ownerDesc,proto3
----- newReflect:
FieldDescriptor{Syntax: proto3, FullName: owner.Owner.owner_id, Number: 1, Cardinality: optional, Kind: int64, HasJSONName: true, JSONName: "ownerId"}
FieldDescriptor{Syntax: proto3, FullName: owner.Owner.owner_name, Number: 2, Cardinality: optional, Kind: string, HasJSONName: true, JSONName: "ownerName"}
FieldDescriptor{Syntax: proto3, FullName: owner.Owner.owner_desc, Number: 16, Cardinality: optional, Kind: string, HasJSONName: true, JSONName: "ownerDesc"}
--- PASS: Test_doReflect (0.00s)
PASS

Process finished with the exit code 0

請注意它們的不同之處,尤其是以“XXX_”開頭的字段。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM