GO 反射编程 个人理解查找数据类型
2022年1月18日
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 |
package reflect_test 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("浮点") case reflect.Int, reflect.Int32, reflect.Int64: fmt.Println("整数") default: fmt.Println("未定义", t) } } /** * 测试自定义数据类型 */ func TestBasicType(t *testing.T) { var f float64 = 12 CheckType(f) //64浮点 CheckType(&f) //64浮点指针 } /** * 测试数值判断 */ func TestDeepEqual(t *testing.T) { a := map[int]string{1: "one", 2: "two", 3: "three"} b := map[int]string{1: "one", 2: "two", 3: "three"} t.Log("a==b?", reflect.DeepEqual(a, b)) s1 := []int{1, 2, 3} s2 := []int{1, 2, 3} s3 := []int{2, 3, 1} t.Log("s1 == s2?", reflect.DeepEqual(s1, s2)) t.Log("s1 == s3?", reflect.DeepEqual(s1, s3)) c1 := Customer{"1", "Mike", 40} c2 := Customer{"1", "Mike", 40} t.Log(c1 == c2) t.Log(reflect.DeepEqual(c1, c2)) } /** * 声明结构 */ type Employee struct { EmployeeID string Name string `format:"normal"` 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")) //查找 Employee 这个结构有没有 name 这个值 if nameField, ok := reflect.TypeOf(*e).FieldByName("Name"); ok { t.Log("Employee 找到了Name结果:", nameField.Tag.Get("format")) t.Log(ok) } else { t.Log("Employee 找不到Name", ok) } reflect.ValueOf(e).MethodByName("UpdateAge").Call([]reflect.Value{reflect.ValueOf(1)}) t.Log("Updated Age:", e) } |
利用反射写一个 将map 数据 赋值到 任意接口得方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 |
package flexible_reflect import ( "errors" "reflect" "testing" ) /** * map 使用 DeepEqual 比较 */ func TestDeepEqual(t *testing.T) { a := map[int]string{1: "one", 2: "two", 3: "three"} b := map[int]string{1: "one", 2: "two", 3: "three"} //t.Log(a == b) map 不能直接比较的 t.Log(reflect.DeepEqual(a, b)) s1 := []int{1, 2, 3} s2 := []int{1, 2, 3} s3 := []int{2, 3, 1} t.Log("s1 == s2?", reflect.DeepEqual(s1, s2)) t.Log("s1 == s3?", reflect.DeepEqual(s1, s3)) } /** * 定义一个结构 */ type Employee struct { EmployeeID string Name string `format:"normal"` Age int } /** * 更具这个结构写一个更新年龄的方法 */ func (e *Employee) UpdateAge(newVal int) { e.Age = newVal } /** * 定义一个结构 */ type Customer struct { CookieID string Name string Age int } /** * 这是一个将map 数据 赋值到 任意接口得方法 */ func fillBySettings(st interface{}, settings map[string]interface{}) error { //种类不等于 Ptr if reflect.TypeOf(st).Kind() != reflect.Ptr { return errors.New("the first param should be a pointer to the struct type.") } //种类不等于 Struct if reflect.TypeOf(st).Elem().Kind() != reflect.Struct { return errors.New("the first param should be a pointer to the struct type.") } //等于 nil if settings == nil { return errors.New("settings is nil.") } //创建两个变量 var ( field reflect.StructField ok bool ) //循环setting for k, v := range settings { //不对就继续 if field, ok = (reflect.ValueOf(st)).Elem().Type().FieldByName(k); !ok { continue } if field.Type == reflect.TypeOf(v) { vstr := reflect.ValueOf(st) vstr = vstr.Elem() vstr.FieldByName(k).Set(reflect.ValueOf(v)) } } return nil //nil 代表正常 } func TestFillNameAndAge(t *testing.T) { settings := map[string]interface{}{"Name": "Mike", "Age": 30} e := Employee{} if err := fillBySettings(&e, settings); err != nil { t.Fatal(err) } t.Log(e) c := new(Customer) if err := fillBySettings(c, settings); err != nil { t.Fatal(err) } t.Log(*c) } |