乐趣区

关于golang:golang-反射原理

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

退出移动版