12.元编程

予早 2025-02-21 01:08:21
Categories: Tags:

反射可以在运行时动态获取变量的信息,如变量的类型、变量的类别,结构体的字段和方法,可以动态修改变量值,直接调用结构体方法

Go反射基本使用流程

对基本数据类型进行反射

package main

import (
    "fmt"
    "reflect"
)

func reflectDemo(i interface{}) {

    t := reflect.TypeOf(i)
    fmt.Println(t)        // int
    fmt.Printf("%T\n", t) // *reflect.rtype

    v := reflect.ValueOf(i)
    fmt.Println(v)        // 100
    fmt.Printf("%T\n", v) // reflect.Value

    k := v.Kind()
    fmt.Println(k)        // int
    fmt.Printf("%T\n", k) // reflect.Kind

    // 类型转换
    fmt.Println(v.Int()) // 100
}

func main() {
    reflectDemo(100)
}

对结构体进行反射

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])
}