golang 反射原理 - Go语言中文社区

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使用的就是这种方式编码和解码

版权声明:本文来源Segmentfault,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://segmentfault.com/a/1190000039979391
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。
  • 发表于 2021-06-13 18:02:17
  • 阅读 ( 783 )
  • 分类:Go

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢