变量的内在机制

类型信息:是静态的元信息,是预先定义好的

值信息:是程序运行过程中动态改变的

反射的使用

获取类型信息: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)
}
调用
package main

import (
    "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)
    }
}

smallsha
14 声望0 粉丝