一、反射获取值和类型

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

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.Int16, reflect.Int64:
		fmt.Println("Integer")
	default:
		fmt.Println("Unknown")
	}
}
func TestBaseicType(t *testing.T) {
	f1 := 3.2
	i1 := 10
	flag := true
	CheckType(f1)
	CheckType(i1)
	CheckType(flag)
}
=== RUN   TestTypeAndValue
    reflect_test.go:12: int64 10
    reflect_test.go:14: int64
--- PASS: TestTypeAndValue (0.00s)
PASS

=== RUN   TestBaseicType
Float
Integer
Unknown
--- PASS: TestBaseicType (0.00s)
PASS
二、反射获取结构体的成员和调用方法

按名字访问结构的成员:reflect.TypeOf(*e).FieldByName("Name")

按名字访问结构的方法:reflect.ValueOf(e).MethodByName("UpdateAge"). Call([]reflect.Value{reflect.ValueOf(1)})

type Employee struct {
	Id   string
	Name string
	Age  int
}

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

func TestInvokeByName(t *testing.T) {
	e := &Employee{"1", "Mike", 30}
	//	按名字获取成员
	t.Logf("Name:value(%[1]v),Type(%[1]T)", reflect.ValueOf(*e).FieldByName("Name"))
	//reflect.TypeOf 返回字段值/字段是否存在
	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"))
	}
	//反射获取公有方法,并调用
	reflect.ValueOf(e).MethodByName("UpdateAge").
		Call([]reflect.Value{reflect.ValueOf(1)})
	t.Log("updateAge Age:", e)
}
=== RUN   TestInvokeByName
    reflect_test.go:55: Name:value(Mike),Type(reflect.Value)
    reflect_test.go:60: Tag:format 
    reflect_test.go:65: updateAge Age: &{1 Mike 1}
--- PASS: TestInvokeByName (0.00s)
PASS