Go reflection class instance

Time:2021-12-2

Internal mechanism of variables

Type information: static meta information, predefined

Value information: it is dynamically changed during program operation

Use of reflection

Get type information: reflect.typeof, which is static

Get value information: reflect.valueof, which is dynamic

Get interface value information by reflection

package main

import (
    "fmt"
    "reflect"
)

//Get interface value information by reflection

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 yes:", V. float())
    }
}

func main() {
    var x float64 = 3.4
    reflect_value(x)
}

Reflection modification value information

package main

import (
    "fmt"
    "reflect"
)

//Reflection modification value
func reflect_set_value(a interface{}) {
    v := reflect.ValueOf(a)
    k := v.Kind()
    switch k {
    case reflect.Float64:
        //Reflection modification value
        v.SetFloat(6.9)
        fmt.Println("a is ", v.Float())
    case reflect.Ptr:
        //Elem() gets the value pointed to by the address
        v.Elem().SetFloat(7.9)
        fmt.Println("case:", v.Elem().Float())
        //Address
        fmt.Println(v.Pointer())
    }
}

func main() {
    var x float64 = 3.4
    //Reflection thinks that the following is a pointer type, not a float type
    reflect_set_value(&x)
    fmt.Println("main:", x)
}

Structure and reflection

View types, fields, and methods

package main

import (
    "fmt"
    "reflect"
)

//Define structure
type User struct {
    Id   int
    Name string
    Age  int
}

//Binding method
func (u User) Hello() {
    fmt.Println("Hello")
}

//Incoming interface {}
func Poni(o interface{}) {
    t := reflect.TypeOf(o)
    FMT. Println ("type:", t)
    FMT. Println ("string type:", t.name())
    //Get value
    v := reflect.ValueOf(o)
    fmt.Println(v)
    //All properties can be obtained
    //Get the number of structure fields: t.numfield()
    for i := 0; i < t.NumField(); i++ {
        //Take each field
        f := t.Field(i)
        fmt.Printf("%s : %v", f.Name, f.Type)
        //Get the value information of the field
        //Interface (): get the value corresponding to the field
        val := v.Field(i).Interface()
        fmt.Println("val :", val)
    }
    FMT. Println ("method =============================================")
    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)
}

View anonymous fields

package main

import (
    "fmt"
    "reflect"
)

//Define structure
type User struct {
    Id   int
    Name string
    Age  int
}

//Anonymous field
type Boy struct {
    User
    Addr string
}

func main() {
    m := Boy{User{1, "zs", 20}, "bj"}
    t := reflect.TypeOf(m)
    fmt.Println(t)
    //Anonymous: Anonymous
    fmt.Printf("%#v\n", t.Field(0))
    //Value information
    fmt.Printf("%#v\n", reflect.ValueOf(m).Field(0))
}

Change the value of the structure

package main

import (
    "fmt"
    "reflect"
)

//Define structure
type User struct {
    Id   int
    Name string
    Age  int
}

//Modify structure values
func SetValue(o interface{}) {
    v := reflect.ValueOf(o)
    //Gets the element pointed to by the pointer
    v = v.Elem()
    //Fetch field
    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)
}

Call method

package main

import (
    "fmt"
    "reflect"
)

//Define structure
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)
    //Acquisition method
    m := v.MethodByName("Hello")
    //Build some parameters
    args := []reflect.Value{reflect.ValueOf("6666")}
    //Without parameters: VAR args2 [] reflect.value
    //To call a method, you need to pass in the parameters of the method
    m.Call(args)
}

Get the tag of the field

package main

import (
    "fmt"
    "reflect"
)

type Student struct {
    Name string `json:"name1" db:"name2"`
}

func main() {
    var s Student
    v := reflect.ValueOf(&s)
    //Type
    t := v.Type()
    //Get field
    f := t.Elem().Field(0)
    fmt.Println(f.Tag.Get("json"))
    fmt.Println(f.Tag.Get("db"))
}

example

method

package common

import (
    "errors"
    "reflect"
    "strconv"
    "time"
)

//Map the data to the structure according to the SQL tag in the structure and convert the type
func DataToStructByTagSql(data map[string]string, obj interface{}) {
    objValue := reflect.ValueOf(obj).Elem()
    for i := 0; i < objValue.NumField(); i++ {
        //Get the value corresponding to SQL
        value := data[objValue.Type().Field(i).Tag.Get("sql")]
        //Get the name of the corresponding field
        name := objValue.Type().Field(i).Name
        //Get the corresponding field type
        structFieldType := objValue.Field(i).Type()
        //Get the variable type, or write "string type" directly
        val := reflect.ValueOf(value)
        var err error
        if structFieldType != val.Type() {
            //Type conversion
            val, err = TypeConversion(value, structFieldType.Name()) //Type conversion
            if err != nil {

            }
        }
        //Set type value
        objValue.FieldByName(name).Set(val)
    }
}

//Type conversion
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....... Add some other types of conversions

    Return reflect. Valueof (value), errors. New ("unknown type:" + ntype)
}

call

package main

import (
    "fmt"

    "github.com/student/1129/common"
)

//Product defines a structure
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() {
    //This is to simulate Mysql to obtain a single piece of data and reflect it to the structure
    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)
    //This is to simulate Mysql to get all the data reflected to the structure
    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)
    }
}