一、反射获取值和类型
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