文章目录
GoLang之图解反射
注:本文基于Windos系统上Go SDK v1.18进行讲解
1.前言
2.Type
//reflect/type.go
type Type interface {
//以下是所有kind通用的方法
Align() int //对齐边界
FieldAlign() int //作为结构体字段的对齐边界
Method(int) Method //获取方法数组中第i个Method
MethodByName(string) (Method, bool) //按照名称查找方法
NumMethod() int //方法列表中可导出方法的数目
Name() string //类型名称
PkgPath() string //包路径
Size() uintptr //该类型变量占用字节数
String() string //获取类型的字符串表示
Kind() Kind //类型对应的reflect.Kind
Implements(u Type) bool //该类型是否实现了接口u
AssignableTo(u Type) bool //是否可以赋值给类型u
ConvertibleTo(u Type) bool //是否可转换为类型u
Comparable() bool //是否可比较
//以下是某些Kind的方法
//Int*, Uint*, Float*, Complex*:
Bits() int
//Array,Ptr,Slice,Map:
Elem() Type
//Array
Len() int
//Chan:ChanDir, Elem
ChanDir() ChanDir
//Func:
In(i int) Type
NumIn() int
Out(i int) Type
NumOut() int
IsVariadic() bool
//Map:
Key() Type
//Struct:
Field(i int) StructField
FieldByIndex(index []int) StructField
FieldByName(name string) (StructField, bool)
FieldByNameFunc(match func(string) bool) (StructField, bool)
NumField() int
common() *rtype
uncommon() *uncommonType
}
//reflect/type.go
func TypeOf(i any) Type {
eface := *(*emptyInterface)(unsafe.Pointer(&i))
return toType(eface.typ)
}
//builtin/builtin.go
type any = interface{}
a := "eggo"
t := reflect.TypeOf(a)
var ret reflect.Type
ret = eface.typ
//fmt/print.go
type Stringer interface {
String() string
}
var i interface{}
a := 1
i = a
fmt.Println(a) //1
fmt.Println(i) //1
i = 5
fmt.Println(a) //1
fmt.Println(i) //5
var i interface{}
a := 1
i = a
fmt.Println(a) //1
fmt.Println(i) //1
a = 9
fmt.Println(a) //9
fmt.Println(i) //1
var ii interface{}
aa := []int{1, 2, 3}
ii = aa
fmt.Println(ii) //[1 2 3]
fmt.Println(aa) //[1 2 3]
aa[1] = 5
fmt.Println(ii) //[1 5 3]
fmt.Println(aa) //[1 5 3]
3.Value
//reflect/value.go
type Value struct {
typ *rtype
ptr unsafe.Pointer
flag
}
//reflect/type.go
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
// function for comparing objects of this type
// (ptr to object A, ptr to object B) -> ==?
equal func(unsafe.Pointer, unsafe.Pointer) bool
gcdata *byte // garbage collection data
str nameOff // string form
ptrToThis typeOff // type for pointer to this type, may be zero
}
func main() {
a := "eggo"
v := reflect.ValueOf(a)
v.SetString("new eggo") //panic: reflect: reflect.Value.SetString using unaddressable value 运行错误
println(a)
}
//reflect/value.go
func ValueOf(i any) Value {
if i == nil {
return Value{}
}
escapes(i)
return unpackEface(i)
}
panic: reflect: reflect.Value.SetString using unaddressable value
func main() {
a := "eggo"
v := reflect.ValueOf(&a)
v.Elem().SetString("new eggo")
println(a) //new eggo
}