本文章次要解说一下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 mainimport "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 mainimport "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应用的就是这种形式编码和解码