反射就是程序在运行时能够检测自身和修改自身的一种能力。
用途#
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