Go反射编程

go 语言每个对象都包含两个部分:类型和值。go 语言的反射也会返回类型和值

reflect.TypeOf 和 reflect.ValueOf

  • reflect.TypeOf 返回类型(reflect.Type)
  • reflect.ValueOf 返回值(reflect.Value)
  • 可以从 reflect.ValueOf(f).Type() 获得类型
  • 通过 kind 的来判断类型
package reflect_learn

import (
    "fmt"
    "reflect"
    "testing"
)

// 获取类型和值
func TestTypeAndValue(t *testing.T) {
    var f int64 = 10
    t.Log(reflect.TypeOf(f), reflect.ValueOf(f))
    t.Log(reflect.ValueOf(f).Type())
}

// 类型检测
func CheckType(v interface{}) {
    t := reflect.TypeOf(v)
    switch t.Kind() {
    case reflect.Float32, reflect.Float64:
        fmt.Println("Float")
    case reflect.Int, reflect.Int32, reflect.Int64:
        fmt.Println("Integer")
    default:
        fmt.Println("Unknown", t)
    }
}

// 类型检测测试
func TestBasicType(t *testing.T) {
    var f float64 = 12
    CheckType(f)
    CheckType(&f)
}

反射普遍用途

通过字符串的方式操作成员和方法

package reflect_learn

import (
    "fmt"
    "reflect"
    "testing"
)

type Employee struct {
    EmployeeID string
    Name       string `format:"name"`
    Age        int
}

func (e *Employee) UpdateAge(newVal int) {
    e.Age = newVal
}

type Customer struct {
    CookieID string
    Name     string
    Age      int
}

func TestInvokeByName(t *testing.T) {
    e := &Employee{"1", "Mike", 30}
    // 通过字符串获取成员
    t.Logf("Name: value(%[1]v), Type(%[1]T)", reflect.ValueOf(*e).FieldByName("Name"))
    if nameField, ok := reflect.TypeOf(*e).FieldByName("Name"); !ok {
        t.Error("Failed to get 'Name' field.")
    } else {
        t.Log("Tag:format", nameField.Tag.Get("format"))
    }
    // 通过字符串获取方法并调用
    // Call 中的参数为 []reflect.Value{}
    // 需要把 int 转为 reflect.Value 类型: reflect.ValueOf(18)
    // 再将上一步的结果放入切片 []reflect.Value{} 中
    reflect.ValueOf(e).MethodByName("UpdateAge").Call([]reflect.Value{reflect.ValueOf(18)})
    t.Log("Updated Age:", e)
}

猜你喜欢

转载自www.cnblogs.com/wuyongqiang/p/12155609.html