繁体   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