变量的内在机制
类型信息:是静态的元信息,是预先定义好的
值信息:是程序运行过程中动态改变的
反射的使用获取类型信息:reflect.TypeOf,是静态的
获取值信息:reflect.ValueOf,是动态的
反射获取interface值信息
package main import ( "fmt" "reflect" ) //反射获取interface值信息 func reflect_value(a interface{}) { v := reflect.ValueOf(a) fmt.Println(v) k := v.Kind() fmt.Println(k) switch k { case reflect.Float64: fmt.Println("a是:", v.Float()) } } func main() { var x float64 = 3.4 reflect_value(x) }反射修改值信息
package main import ( "fmt" "reflect" ) //反射修改值 func reflect_set_value(a interface{}) { v := reflect.ValueOf(a) k := v.Kind() switch k { case reflect.Float64: // 反射修改值 v.SetFloat(6.9) fmt.Println("a is ", v.Float()) case reflect.Ptr: // Elem()获取地址指向的值 v.Elem().SetFloat(7.9) fmt.Println("case:", v.Elem().Float()) // 地址 fmt.Println(v.Pointer()) } } func main() { var x float64 = 3.4 // 反射认为下面是指针类型,不是float类型 reflect_set_value(&x) fmt.Println("main:", x) } 结构体与反射查看类型、字段和方法
package main import ( "fmt" "reflect" ) // 定义结构体 type User struct { Id int Name string Age int } // 绑方法 func (u User) Hello() { fmt.Println("Hello") } // 传入interface{} func Poni(o interface{}) { t := reflect.TypeOf(o) fmt.Println("类型:", t) fmt.Println("字符串类型:", t.Name()) // 获取值 v := reflect.ValueOf(o) fmt.Println(v) // 可以获取所有属性 // 获取结构体字段个数:t.NumField() for i := 0; i < t.NumField(); i++ { // 取每个字段 f := t.Field(i) fmt.Printf("%s : %v", f.Name, f.Type) // 获取字段的值信息 // Interface():获取字段对应的值 val := v.Field(i).Interface() fmt.Println("val :", val) } fmt.Println("=================方法====================") for i := 0; i < t.NumMethod(); i++ { m := t.Method(i) fmt.Println(m.Name) fmt.Println(m.Type) } } func main() { u := User{1, "zs", 20} Poni(u) }查看匿名字段
package main import ( "fmt" "reflect" ) // 定义结构体 type User struct { Id int Name string Age int } // 匿名字段 type Boy struct { User Addr string } func main() { m := Boy{User{1, "zs", 20}, "bj"} t := reflect.TypeOf(m) fmt.Println(t) // Anonymous:匿名 fmt.Printf("%#v\n", t.Field(0)) // 值信息 fmt.Printf("%#v\n", reflect.ValueOf(m).Field(0)) }修改结构体的值
package main import ( "fmt" "reflect" ) // 定义结构体 type User struct { Id int Name string Age int } // 修改结构体值 func SetValue(o interface{}) { v := reflect.ValueOf(o) // 获取指针指向的元素 v = v.Elem() // 取字段 f := v.FieldByName("Name") if f.Kind() == reflect.String { f.SetString("kuteng") } } func main() { u := User{1, "5lmh.com", 20} SetValue(&u) fmt.Println(u) }调用方法
package main import ( "fmt" "reflect" ) // 定义结构体 type User struct { Id int Name string Age int } func (u User) Hello(name string) { fmt.Println("Hello:", name) } func main() { u := User{1, "5lmh.com", 20} v := reflect.ValueOf(u) // 获取方法 m := v.MethodByName("Hello") // 构建一些参数 args := []reflect.Value{reflect.ValueOf("6666")} // 没参数的情况下:var args2 []reflect.Value // 调用方法,需要传入方法的参数 m.Call(args) }获取字段的tag
package main import ( "fmt" "reflect" ) type Student struct { Name string `json:"name1" db:"name2"` } func main() { var s Student v := reflect.ValueOf(&s) // 类型 t := v.Type() // 获取字段 f := t.Elem().Field(0) fmt.Println(f.Tag.Get("json")) fmt.Println(f.Tag.Get("db")) } 实例方法
package common import ( "errors" "reflect" "strconv" "time" ) //根据结构体中sql标签映射数据到结构体中并且转换类型 func DataToStructByTagSql(data map[string]string, obj interface{}) { objValue := reflect.ValueOf(obj).Elem() for i := 0; i < objValue.NumField(); i++ { //获取sql对应的值 value := data[objValue.Type().Field(i).Tag.Get("sql")] //获取对应字段的名称 name := objValue.Type().Field(i).Name //获取对应字段类型 structFieldType := objValue.Field(i).Type() //获取变量类型,也可以直接写"string类型" val := reflect.ValueOf(value) var err error if structFieldType != val.Type() { //类型转换 val, err = TypeConversion(value, structFieldType.Name()) //类型转换 if err != nil { } } //设置类型值 objValue.FieldByName(name).Set(val) } } //类型转换 func TypeConversion(value string, ntype string) (reflect.Value, error) { if ntype == "string" { return reflect.ValueOf(value), nil } else if ntype == "time.Time" { t, err := time.ParseInLocation("2006-01-02 15:04:05", value, time.Local) return reflect.ValueOf(t), err } else if ntype == "Time" { t, err := time.ParseInLocation("2006-01-02 15:04:05", value, time.Local) return reflect.ValueOf(t), err } else if ntype == "int" { i, err := strconv.Atoi(value) return reflect.ValueOf(i), err } else if ntype == "int8" { i, err := strconv.ParseInt(value, 10, 64) return reflect.ValueOf(int8(i)), err } else if ntype == "int32" { i, err := strconv.ParseInt(value, 10, 64) return reflect.ValueOf(int64(i)), err } else if ntype == "int64" { i, err := strconv.ParseInt(value, 10, 64) return reflect.ValueOf(i), err } else if ntype == "float32" { i, err := strconv.ParseFloat(value, 64) return reflect.ValueOf(float32(i)), err } else if ntype == "float64" { i, err := strconv.ParseFloat(value, 64) return reflect.ValueOf(i), err } //else if .......增加其他一些类型的转换 return reflect.ValueOf(value), errors.New("未知的类型:" + ntype) }