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就是字符串。

  • 相关阅读:
    LeetCode Subsets II
    LeetCode Rotate Image
    LeetCode Palidrome Number
    LeetCode Generate Parentheses
    LeetCode Maximum Subarray
    LeetCode Set Matrix Zeroes
    LeetCode Remove Nth Node From End of List
    Linux Loop设备 使用
    Linux 文件系统大小调整
    LeetCode N-Queens II
  • 原文地址:https://www.cnblogs.com/lanyangsh/p/11143680.html
Copyright © 2011-2022 走看看