golang的反射机制

写一段最简单的代码看看golang的反射机制是怎么做的。

import (
	"fmt"
	"reflect"
)

func main() {
 	var a int
 	typeOfA := reflect.TypeOf(a)
 	fmt.Println(typeOfA.String())
	fmt.Println(typeOfA.Kind())
}

看看这个TypeOf是怎么实现的

func TypeOf(i interface{}) Type {
	eface := *(*emptyInterface)(unsafe.Pointer(&i))
	return toType(eface.typ)
}

这里的Type是一个Interface{},看不出是什么。

这个unsafe.Pointer是个什么?

type Pointer *ArbitraryType
type ArbitraryType int

原来是个指针,存储内存地址。只是有点好奇,这个int在32系统下是不是就4字节,而在64系统下就是8个字节?有待求证啊。

再看看那个emptyInterface,名字取得真怪,空接口,这是什么鬼?

// emptyInterface is the header for an interface{} value.
type emptyInterface struct {
	typ  *rtype
	word unsafe.Pointer
}

原来是个结构体。注释说它表示interface{}的头部。它有两个字段。后面的那个好像没什么意思,就一指针,有更多内容的是第一个字段,进去看看。

// rtype is the common implementation of most values.
// It is embedded in other struct types.
//
// rtype must be kept in sync with ../runtime/type.go:/^type._type.
type rtype struct {
	size       uintptr
	ptrdata    uintptr  // number of bytes in the type that can contain pointers
	hash       uint32   // hash of type; avoids computation in hash tables
	tflag      tflag    // extra type information flags
	align      uint8    // alignment of variable with this type
	fieldAlign uint8    // alignment of struct field with this type
	kind       uint8    // enumeration for C
	alg        *typeAlg // algorithm table
	gcdata     *byte    // garbage collection data
	str        nameOff  // string form
	ptrToThis  typeOff  // type for pointer to this type, may be zero
}

果然是很有料。好像是定义了类型的大多数属性,存储大小,对齐什么的,暂时也搞不明白。注释说它用来嵌入其他结构体类型,看看它怎么用的。

type arrayType struct {
	rtype
	elem  *rtype // array element type
	slice *rtype // slice type
	len   uintptr
}

// chanType represents a channel type.
type chanType struct {
	rtype
	elem *rtype  // channel element type
	dir  uintptr // channel direction (ChanDir)
}

type funcType struct {
	rtype
	inCount  uint16
	outCount uint16 // top bit is set if last input parameter is ...
}

还有很多就不列举了,看来rtype真的是嵌入其他结构体里。暂时不扩展那么开,调试一下看看运行流程是怎么样的。

结果我运行后,就发现这么一个现象:

调试运行到这里的时候,就发现eface值就突然多了很多值,也不知道是在哪里赋值的。好像是突然冒出来的。这里也没有赋值的地方啊,只是把它的地址类型转换了一下而已。这怎么解释这种现象?

我想应该是在这里

func TypeOf(i interface{}) Type {

这个函数的参数是一个interface{}。

当把一个int类型的变量传入这个函数时,会构建一个interface{}类型的内存区域。因为golang的语法保证任何类型都可以转换为interface{} 而不会引发错误,所以可以把interface{}看作是一种特殊的struct。当把其他类型转换为interface{}的时候,会开辟一块内存空间存储一些跟原来类型相关的数据,就像上面那个图里显示的那些数据一样。

所以反射的本质是什么呢?

反射的本质就是把其他类型转换为interface{}的时候,会自动为其他类型开辟一块内存区域,存储跟那个类型有关的数据。

后面调用各种函数都是对这些数据的一些读取转换操作而已。

(全文完)

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值