本文章次要解说一下 reflect 包中 TypeOf 和 ValueOf 两个函数的工作原理。
TypeOf
在 Go 语言中通过调用 reflect.TypeOf 函数,咱们能够从一个任何非接口类型的值创立一个 reflect.Type 值。reflect.Type 值示意着此非接口值的类型。通过此值,咱们能够失去很多此非接口类型的信息。当然,咱们也能够将一个接口值传递给一个 reflect.TypeOf 函数调用,然而此调用将返回一个示意着此接口值的动静类型的 reflect.Type 值。
实际上,reflect.TypeOf 函数的惟一参数的类型为 interface{},reflect.TypeOf 函数将总是返回一个示意着此惟一接口参数值的动静类型的 reflect.Type 值。
TypeOf 的源码如下
type eface struct{
_type *_type
data unsafe.Pointer
}
type emptyInterface struct{
typ *rtype
word unsafe.Pointer
}
func TypeOf (i interface()) Type{eface := *(* emptyInterface)(unsafe.Pointer(&i)) //&i 是 eface 类型
return toType(eface.typ)
}
这里是反射的一些简略利用
package main
import "fmt"
import "reflect"
type Eggo struct{name string}
func (e Eggo) A(){fmt.Println(e.name)
}
func main() {a := Eggo{name:"eggo"}
t:=reflect.TypeOf(a)
fmt.Println(t.NumMethod(),t.Kind(),t)
}
输入如下:1 struct main.Eggo。t.Kind() 会返回 golang 原始类型,原始类型 string,struct 等等
package main
import "fmt"
import "reflect"
import "encoding/json"
type Stu struct {
Name string `json:"name"`
Age int
HIgh bool
sex string
Class *Class `json:"class"`
}
type Class struct {
Name string
Grade int
}
type Eggo struct{Name string}
func (e Eggo) A(){fmt.Println(e.Name)
}
func main() {
/*
stu := Stu{
Name: "张三",
Age: 18,
HIgh: true,
sex: "男",
}
// 指针变量
cla := new(Class)
cla.Name = "1 班"
cla.Grade = 3
stu.Class=cla
//Marshal 失败时 err!=nil
jsonStu, err := json.Marshal(stu)
if err != nil {fmt.Println("生成 json 字符串谬误")
}
//jsonStu 是 []byte 类型,转化成 string 类型便于查看
fmt.Println(string(jsonStu))*/
a := Eggo{Name:"eggo"}
b := &Eggo{}
bdata, err:= json.Marshal(a)
if err != nil {fmt.Println("生成 json 字符串谬误")
}
t:=reflect.TypeOf(a)
fmt.Println(string(bdata))
aa := reflect.New(t).Interface()
fmt.Println("...........",t,aa,b)
json.Unmarshal(bdata, aa)
fmt.Println("reflect-get-name",(aa).(*Eggo).Name)
}
输入如下:
{“Name”:”eggo”}
……….. main.Eggo &{} &{}
reflect-get-name eggo。
依据反射解析 json。cellnet 应用的就是这种形式编码和解码