跳过正文
  1. 全部/
  2. 笔记/
  3. 面试/
  4. golang/

反射

目录

反射就是程序在运行时能够检测自身和修改自身的一种能力。

用途
#

json 序列化和反序列化 ORM 配置文件解析yaml,ini

reflect
#

reflect.TypeOf()
#

func reflectType(x interface{}){
	obj := reflect.TypeOf(x)
	fmt.Println(obj)
}
package main

import (
	"fmt"
	"reflect"
)

type myInt int64

func reflectType(x interface{}) {
	t := reflect.TypeOf(x)
	fmt.Printf("type:%v kind:%v\n", t.Name(), t.Kind())
}

func main() {
	var a *float32 // 指针
	var b myInt    // 自定义类型
	var c rune     // 类型别名
	reflectType(a) // type: kind:ptr
	reflectType(b) // type:myInt kind:int64
	reflectType(c) // type:int32 kind:int32

	type person struct {
		name string
		age  int
	}
	type book struct{ title string }
	var d = person{
		name: "沙河小王子",
		age:  18,
	}
	var e = book{title: "《跟小王子学Go语言》"}
	reflectType(d) // type:person kind:struct
	reflectType(e) // type:book kind:struct
}

Go语言的反射中像数组、切片、Map、指针等类型的变量,它们的.Name()都是返回

reflect.ValueOf()
#

func reflectValue(x interface{}) {
	v := reflect.ValueOf(x)
	k := v.Kind()
	switch k {
	case reflect.Int64:
		// v.Int()从反射中获取整型的原始值,然后通过int64()强制类型转换
		fmt.Printf("type is int64, value is %d\n", int64(v.Int()))
	case reflect.Float32:
		// v.Float()从反射中获取浮点型的原始值,然后通过float32()强制类型转换
		fmt.Printf("type is float32, value is %f\n", float32(v.Float()))
	case reflect.Float64:
		// v.Float()从反射中获取浮点型的原始值,然后通过float64()强制类型转换
		fmt.Printf("type is float64, value is %f\n", float64(v.Float()))
	}
}
func main() {
	var a float32 = 3.14
	var b int64 = 100
	reflectValue(a) // type is float32, value is 3.140000
	reflectValue(b) // type is int64, value is 100
	// 将int类型的原始值转换为reflect.Value类型
	c := reflect.ValueOf(10)
	fmt.Printf("type c :%T\n", c) // type c :reflect.Value
}

结构体反射
#

type student struct{
	Name string `json:"name" ini:"ini_name"`
	Score int `json:"int" ini:"ini_int"`
}

JSON 序列化
#

package main

  

import (

    "fmt"

    "reflect"

    "strconv"

    "strings"

)

  

type User struct {

    Name string

    Age  int

}

  

func main() {

    var u User = User{"Tom", 10}

    tp := reflect.TypeOf(u)

    val := reflect.ValueOf(u)

    for i := range tp.NumField() {

        tpfield := tp.Field(i)

        valField := val.Field(i)

        fmt.Print(tpfield.Name)

        switch valField.Kind() {

        case reflect.String:

            fmt.Print(valField.String())

        case reflect.Int:

            fmt.Print(valField.Int())

        }

    }

    main2()

}

  

func main2() {

    var u User

    str := `{"Name":"Tom","Age":18}`

    val := reflect.ValueOf(&u).Elem()

    parts := strings.SplitSeq(strings.Trim(str, "{}"), ",")

    for part := range parts {

        p := strings.Split(part, ":")

        pkey := strings.Trim(p[0], "\"")

        pval := strings.Trim(p[1], "\"")

        field := val.FieldByName(pkey)

        switch field.Kind() {

        case reflect.Int:

            v, _ := strconv.Atoi(pval)

            field.SetInt(int64(v))

        case reflect.String:

            field.SetString(pval)

        }

    }

    fmt.Println(u)

}
reflect.TypeOf(v)通过NumField()获取Name以及Tag
Reply by Email