zoukankan      html  css  js  c++  java
  • 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或指针。

    2.3 Type.Elem()

    type Type Interface{
        // Elem returns a type's element type.
    	// It panics if the type's Kind is not Array, Chan, Map, Ptr, or Slice.
    	Elem() Type
    	... ...
    }
    

    返回指向对象的具体类型。
    要求调用者必须是Array, Chan, Map, Ptr, or Slice

    例如,

    i := 1
    v := reflect.ValueOf(&i)
    
    valueType := v.Type()
    elemType := valueType.Elem()
    
    fmt.Println("valueType:", valueType) //*int
    fmt.Println("elemType:", elemType) // int
    

    v是*int,则element type就是int

    例如,

    sli := []string{"abc", "ef", "gh", "123"}
    
    v := reflect.ValueOf(sli)
    
    valueType := v.Type()
    elemType := valueType.Elem()
    
    fmt.Println("valueType:", valueType) // []string
    fmt.Println("elemType:", elemType) // string
    

    v是字符串数组,则element type就是字符串。

  • 相关阅读:
    HTTP 常见状态码
    SpringMVC 入门
    Maven 整合SSH框架
    SSH 框架整合总结
    Maven 整合SSH框架之pom.xml
    Maven 入门
    WebService 综合案例
    CXF 框架
    jQuery高级
    JavaScript补充:BOM(浏览器对象模型)
  • 原文地址:https://www.cnblogs.com/lanyangsh/p/11143680.html
Copyright © 2011-2022 走看看