反射操作结构体-获取对象信息

未匹配的标注

获取对象信息

Golang解析结构体标签主要通过反射实现。除上述章节反复使用到的 Typeof()、ValueOf()、Kind()等方法外,还要借助reflect包中的其他方法:

func (v [Value](#Value)) NumField() [int](#int)

返回v持有的结构体类型值的字段数,如果v的Kind不是Struct会panic

func (v Value) Type() Type

返回v持有的值的类型的Type表示。

而Type 是一个interface,包含方法 Field(i int) StructField 返回StructField结构体类型。

StructField类型描述结构体中的一个字段的信息。

type StructField struct {
    // Name是字段的名字。PkgPath是非导出字段的包路径,对导出字段该字段为""。
    // 参见http://golang.org/ref/spec#Uniqueness_of_identifiers
    Name    string
    PkgPath string
    Type      Type      // 字段的类型
    Tag       StructTag // 字段的标签
    Offset    uintptr   // 字段在结构体中的字节偏移量
    Index     []int     // 用于Type.FieldByIndex时的索引切片
    Anonymous bool      // 是否匿名字段
}

StructTag是结构体字段的标签。

type StructTag string

Get方法返回标签字符串中键key对应的值。如果标签中没有该键,会返回""。

func (tag StructTag) Get(key string) string
package main

import (
   "fmt"
   "reflect"
)
const tagName = "Testing"

type Test struct {
   Name string   `json:"-"`    //“-”作用是不进行序列化,效果和将结构体字段写成小写一样。
   Age  int      `json:"age,omitempty"` // “omitempty”作用是在序列化的时候忽略0值或空值。
   Id int        `json:"idx,string"` // 序列化时,类型转化为string
   Sex  string   `json:"sex"`
}
func main() {
   test := Test{"kitty", 18, 61, "female"}

   //通过反射,我们获取变量的动态类型
   reType := reflect.TypeOf(test)
   fmt.Println("Type:", reType.Name())
   fmt.Println("Kind:", reType.Kind())

   for i := 0; i < reType.NumField(); i++ {
      field := reType.Field(i) //获取结构体的每一个字段
      tag := field.Tag.Get(tagName)
      fmt.Printf("%d. %v(%v):%v, TAG:'%v'\n",
            i+1, field.Name, field.Type, reVal.Field(i), tag)
   }
}

输出结果:

1. Name(string):AAA, TAG : -
2. Age(int):18, TAG : age,omitempty
3. Id(int):100, TAG : idx,string
4. Sex(string) :male, TAG : sex

本文章首发在 LearnKu.com 网站上。

上一篇 下一篇
wangchunbo
讨论数量: 0
发起讨论 只看当前版本


暂无话题~