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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM