簡體   English   中英

如何使用reflect從protobuf結構中僅獲取數據(導出)字段?

[英]How to get only data (exported) fields from protobuf struct with reflect?

我的原型文件看起來像這樣

message DeviceOption {
  string ApID = 1;
  string Other = 2;
}

運行DeviceOption后, DeviceOption結構體生成如下:

type DeviceOption struct {
    state         protoimpl.MessageState
    sizeCache     protoimpl.SizeCache
    unknownFields protoimpl.UnknownFields

    ApID  string `protobuf:"bytes,1,opt,name=ApID,proto3" json:"ApID,omitempty"`
    Other string `protobuf:"bytes,2,opt,name=Other,proto3" json:"Other,omitempty"`
}

現在,在服務器中,我想使用https://pkg.go.dev/reflect解析所有可用字段。 我的代碼是這樣的:

v := reflect.ValueOf(pb.DeviceOption{
            ApID: "random1",
            Other: "random2",
        }) 
for i := 0; i < v.NumField(); i++ {
    // Do my thing
}

v.NumField()返回 5,這意味着它包括所有字段,包括我們不需要的statesizeCacheunknownFields 我們只想要ApIDOther

有沒有其他方法可以讓反射只返回數據(導出)字段,而忽略元數據(未導出)字段?

方法NumFields正確返回導出或未導出的字段數。

轉到 1.17 及以上

使用StructField.IsExported

for _, f := range reflect.VisibleFields(v.Type()) {
     if f.IsExported() {
          // do your thing
     }
}

直到 1.16

要知道導出了哪些,請檢查字段PkgPath是否為空。

也可以使用CanSet ,但是 Go 1.17 中StructField.IsExported的實現實際上是f.PkgPath == ""

PkgPath字段上的文檔指出:

PkgPath是限定小寫(未導出)字段名稱的包路徑。 大寫(導出)字段名稱為空。 https://golang.org/ref/spec#Uniqueness_of_identifiers

typ := v.Type()
for i := 0; i < typ.NumField(); i++ {
    if f := typ.Field(i); f.PkgPath == "" {
         // do your thing
    }
}

暫無
暫無

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

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