golang 使用reflect反射结构体

"反射结构体"是指在程序执行时,遍历结构体中的字段以及方法。

1.反射结构体

下面使用一个简单的例子说明如何反射结构体。

定义一个结构体,包括3个字段,以及一个方法。

通过reflect包,首先查看这个结构体对应的动态类型reflect.Type和动态值reflect.Value,并查看这个结构体对应的基本类型。

接着查看结构体的字段数量,并遍历每个字段。
打印每个字段的类型、值、以及tag标签。

最后,调用结构体中的方法,并打印返回结果。

具体代码如下。

package main

import (
    "fmt"
    "reflect"
)

type Orange struct {
    size    int `kitty:"size"`
    Weight  int `kitty:"wgh"`
    From    string  `kitty:"source"`
}

func (this Orange) GetWeight() int  {
    return this.Weight
}

func main(){

    orange := Orange{1, 18, "Shanghai"}

    refValue := reflect.ValueOf(orange) // value

    refType := reflect.TypeOf(orange)  // type

    fmt.Println("orange refValue:", refValue)
    fmt.Println("orange refType:", refType)

    orangeKind := refValue.Kind() // basic type
    fmt.Println("orange Kind:", orangeKind)

    fieldCount := refValue.NumField() // field count
    fmt.Println("fieldCount:", fieldCount)

    for i:=0; i < fieldCount; i++{
        fieldType := refType.Field(i) // field type
        fieldValue := refValue.Field(i) // field vlaue
        fieldTag := fieldType.Tag.Get("kitty") // field tag

        fmt.Println("fieldTag:", fieldTag)
        fmt.Println("field type:", fieldType.Type)
        fmt.Println("fieldValue:", fieldValue)

    }

    // method
    result := refValue.Method(0).Call(nil)
    fmt.Println("method result:", result[0])
}

输出结果:

orange refValue: {1 18 Shanghai}
orange refType: main.Orange
orange Kind: struct
fieldCount: 3
fieldTag: size
field type: int
fieldValue: 1
fieldTag: wgh
field type: int
fieldValue: 18
fieldTag: source
field type: string
fieldValue: Shanghai
method result: 18

另外, 如果反射时,使用的参数是结构体指针:

refValue := reflect.ValueOf(&orange) // value

则需要首先解引用指针,取得指针指向的对象:

refValue = refValue.Elem()

2.相关函数说明

2.1 Value.Kind()

func (v Value) Kind() Kind 

其返回值为Kind,表示golang语言自身定义的基本类型:

type Kind uint 

取值包括:

const (
    Invalid Kind = iota
    Bool
    Int
    Int8
    Int16
    Int32
    Int64
    Uint
    Uint8
    Uint16
    Uint32
    Uint64
    Uintptr
    Float32
    Float64
    Complex64
    Complex128
    Array
    Chan
    Func
    Interface
    Map
    Ptr
    Slice
    String
    Struct
    UnsafePointer
) 

2.2 Value.Elem()

func (v Value) Elem() Value 

方法返回v指向的对象。

要求v必须是interface或指针。

原文地址:https://www.cnblogs.com/lanyangsh/p/11143680.html

时间: 2024-11-08 19:01:49

golang 使用reflect反射结构体的相关文章

golang 兼容不同json结构体解析实践

线上服务器,同一个web接口有时需要兼容不同版本的结构体.这种情况思路是使用interface{}接收任意类型数据,结合reflect包处理. 如下,http接口调用者会传入不同的json结构数据(单体结构或切片结构): type ReqStu struct { XXX struct { //XXX结构为单体 AAA string `json:"aaa"` BBB string `json:"bbb"` CCC string `json:"ccc"

在Golang里如何实现结构体成员指针到结构体自身指针的转换

原文地址:http://goworldgs.com/?p=37 在C语言中有一个经典的宏定义,可以将结构体struct内部的某个成员的指针转化为结构体自身的指针.下面是一个例子,通过FIELD_OFFSET宏计算结构体内一个字段的偏移,函数getT可以从一个F*的指针获得对应的T*对象. struct F { int c; int d; } struct T{ int a; int b; struct F f; } #define FIELD_OFFSET(type, field) ((int)

golang 碎片整理之 结构体

什么是结构体? 结构体(struct)是用户自定义的类型,它代表若干字段的集合,可以用于描述一个实体对象,类似Java中的class,是golang面向对象编程的基础.结构体的概念在软件工程上的旧术语是ADT(抽象数据类型: Abstract Date type).在c++它也是存在,并且名字也是struct,在面向对象的编程语言中,跟一个无方法的轻量级类一样.因为在Go语言中没有类的概念,所以在go中结构体有着很重要的地位. 如何定义一个结构体 type Coordinate struct {

换个语言学一下 Golang (9)——结构体和接口

基本上到这里的时候,就是上了一个台阶了.Go的精华特点即将展开. 结构体定义 上面我们说过Go的指针和C的不同,结构体也是一样的.Go是一门删繁就简的语言,一切令人困惑的特性都必须去掉. 简单来讲,Go提供的结构体就是把使用各种数据类型定义的不同变量组合起来的高级数据类型.闲话不多说,看例子: type Rect struct { width float64 length float64 } 上面我们定义了一个矩形结构体,首先是关键是type表示要定义一个新的数据类型了,然后是新的数据类型名称R

Golang 入门 : 结构体(struct)

Go 通过类型别名(alias types)和结构体的形式支持用户自定义类型,或者叫定制类型.试图表示一个现实世界中的实体. 结构体由一系列命名的元素组成,这些元素又被称为字段,每个字段都有一个名称和一个类型. 结构体的目的就是把数据聚集在一起,以便能够更加便捷地操作这些数据.结构体的概念在 C 语言里很常见,被称为 struct.Golang 中的结构体也是 struct.Go 语言中没有类的概念,因此在 Go 中结构体有着更为重要的地位.结构体是复合类型(composite types),当

golang 使用匿名结构体的问题

golang允许使用匿名结构体,形如 type Test struct { param1 struct { param2 string } } 一般在使用的时候可以直接这样初始化 a := Test{ param1: struct{ param2 string }{param2: "test"}, } 或者 b := new(Test) b.param1.param2 = "test" 但今天遇到一种情况 匿名结构体的成员上有tag声明,形如 type Test s

golang笔记(1)-数据库查询结果映射至结构体

通用的映射模式 query:="select id,name from user where id=?" //单个结构体ret:=&Activity{} DbClient().Find(query,activityId).Unique(ret)//结构体数组ret:=[]Activity{} DbClient().Find(query,activityId).List(&ret)   1.定义结构体 type Activity struct{ ID int64 `col

golang 结构体笔记

一.概念 结构体是一种聚合的数据类型,是由零个或多个任意类型的值聚合成的实体.每个值称为结构体的成员. 二.结构体声明及使用 // 声明结构体 type Employee struct { ID int Name string } func main() { // 结构体实例化 emp := Employee{ID: 1, Name: "Frod"} // 匿名字段实例化 emp2 := Employee{1, "Frod2"} fmt.Println(emp) f

golang结构体json的时间格式化解决方案

最近开发项目时候发现一个结构体的Json转换的时间格式问题. 即这种1993-01-01T20:08:23.000000028+08:00 这种表示UTC方法.从我们习惯来说,更喜欢希望的是 1993-01-01 20:08:23这种格式. 重新复现代码如下: package main import (     "time"     "encoding/json" ) type Student struct {     Name string     `json:&