变量的外在机制

类型信息:是动态的元信息,是事后定义好的

值信息:是程序运行过程中动静扭转的

反射的应用

获取类型信息:reflect.TypeOf,是动态的

获取值信息:reflect.ValueOf,是动静的

反射获取interface值信息

package mainimport (    "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 mainimport (    "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 mainimport (    "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 mainimport (    "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 mainimport (    "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 mainimport (    "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 mainimport (    "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 commonimport (    "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)}
调用
package mainimport (    "fmt"    "github.com/student/1129/common")//Product Product定义一个构造体type Product struct {    ID           int64  `json:"id" sql:"id"`    ProductClass string `json:"ProductClass" sql:"ProductClass"`    ProductName  string `json:"ProductName" sql:"productName"`    ProductNum   int64  `json:"ProductNum" sql:"productNum"`    ProductImage string `json:"ProductImage" sql:"productImage"`    ProductURL   string `json:"ProductUrl" sql:"productUrl" `}func main() {    //这块是模仿mysql获取单条的数据反射到构造体    data := map[string]string{"id": "1", "ProductClass": "blog", "productName": "5lmh.com", "productNum": "40", "productImage": "http://www.5lmh.com/", "productUrl": "http://www.5lmh.com/"}    productResult := &Product{}    common.DataToStructByTagSql(data, productResult)    fmt.Println(*productResult)    //这块是模仿mysql获取所有的数据反射到构造体    Alldata := []map[string]string{        {"id": "1", "ProductClass": "blog", "productName": "5lmh.com", "productNum": "40", "productImage": "http://www.5lmh.com/", "productUrl": "http://www.5lmh.com/"},        {"id": "2", "ProductClass": "blog", "productName": "5lmh.com", "productNum": "40", "productImage": "http://www.5lmh.com/", "productUrl": "http://www.5lmh.com/"},    }    var productArray []*Product    for _, v := range Alldata {        Allproduct := &Product{}        common.DataToStructByTagSql(v, Allproduct)        productArray = append(productArray, Allproduct)    }    for _, vv := range productArray {        fmt.Println(vv)    }}