go-源码研读-reflect
背景介绍
Go
中的反射使用的就是官方提供的reflect
这个包
使用方法
类型reflect.Type
主要是使用reflect.Typeof()
获取到变量的类型信息(reflect.Type
),再通过里面一些方法拿到想要的属性
1 | //a/a.go |
reflect.Type
的方法很多,但是可不可以使用取决于变量本身的类型,比如Len()
方法string
是使用不了的,这里整理了一个表格供大家参考
示例代码位于:
类型 | 可用方法列表 | 用途 | |
---|---|---|---|
通用 | String | 全名称:[包名.]类型名 | |
Kind | 类型 | ||
Name | 类型名 可能为空 | ||
PkgPath | 包名 包名可能为空 | ||
Comparable | 是否可以比较 | ||
Size | 占用字节 | ||
Align | 对齐字节 | ||
Struct | FieldAlign | 字段内存对齐字节 | |
NumField | 字段数 | ||
Field | 根据索引获取字段 | ||
FieldByName | 根据名称获取字段 | ||
NumMethod | 导出的方法数 | ||
Method | 根据索引获取方法,只能访问导出的方法(大写的) | ||
MethodByName | 根据名称获取方法,只能访问导出的方法(大写的) | ||
FieldByIndex | 当struct是嵌套的,这个方法可以找到内嵌的字段,第0个字段的第0个字段 | ||
FieldByNameFunc | 根据所给的方法查找,如果多个匹配返回第一个匹配的 | ||
Func | NumIn | 入参个数 | |
NumOut | 返回值个数 | ||
In | 获取入参索引位置的类型 | ||
Out | 获取返回值索引位置的类型 | ||
IsVariadic | 是否有可变参数 比如… float64 | ||
Channel | ChanDir | channel方向 | |
Array | Len | 长度 | |
Slice | 无 | ||
Map | Key | key的类型 | |
Array,Slice,Channel,Map,Pinter | Elem | 内部元素的类型 | |
数字类型 | Bits | 占用bit数 |
还有几个特殊方法
AssignableTo(v interface{})
判断能不能把v赋值给自己
ConvertibleTo(v interface{})
判断能不能和v进行比较
Implements(v interface{})
v只能传接口,判断有没有实现这个接口,使用起来会比较复杂,下面给出示例
1 | package main |
值reflect.Value
上文所有的操作都是和类型相关的,那么如何对实际的值进行操作呢?
首先得明确一点,那就是Go
的参数传递都是值传递的,所以想要修改本身,得传递自身的指针.
1 | func main() { |
这里可以看到,v
本身是不能修改的,而v.Elem()
v的元素是可以修改的,这是什么意思呢?其实就是 指针的指向是不能修改的,但是指针指向的值可以修改的。
同样,下面整理了一份表格以供查阅
示例代码位于:
原理剖析
进阶理解
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 SHIELD!
评论