go之reflect
更新日期:
reflect中主要包含TypeOf和ValueOf两个函数:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36// TypeOf returns the reflection Type that represents the dynamic type of i.
// If i is a nil interface value, TypeOf returns nil.
func TypeOf(i interface{}) Type {
eface := *(*emptyInterface)(unsafe.Pointer(&i))
return toType(eface.typ)
}
// ValueOf returns a new Value initialized to the concrete value
// stored in the interface i. ValueOf(nil) returns the zero Value.
func ValueOf(i interface{}) Value {
if i == nil {
return Value{}
}
// TODO: Maybe allow contents of a Value to live on the stack.
// For now we make the contents always escape to the heap. It
// makes life easier in a few places (see chanrecv/mapassign
// comment below).
escapes(i)
return unpackEface(i)
}
// unpackEface converts the empty interface i to a Value.
func unpackEface(i interface{}) Value {
e := (*emptyInterface)(unsafe.Pointer(&i))
// NOTE: don't read e.word until we know whether it is really a pointer or not.
t := e.typ
if t == nil {
return Value{}
}
f := flag(t.Kind())
if ifaceIndir(t) {
f |= flagIndir
}
return Value{t, e.word, f}
}
可见,TypeOf直接返回值的类型信息rtype(见上篇博客rtype定义)
ValueOf存储了rtype信息、值的拷贝副本、flag字段
flag标识了该类型是否是指针 是否可寻址 是否包含方法等1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35type test struct {
I int
}
func (t test) Geti() int {
return t.I
}
type I interface {
Geti() int
}
func main() {
a := test{1}
v := reflect.ValueOf(a)
vv := reflect.ValueOf(&a)
vvv := vv.Elem()
var i interface{}
i = &a
n := unsafe.Pointer(&a)
nn := *(*unsafe.Pointer)(n)
vvvv := reflect.ValueOf(i).Elem()
b := test{2}
var bb I
bb = b
s := reflect.ValueOf(bb)
ss := reflect.ValueOf(&bb)//type=*main.I
sss := reflect.ValueOf(&b)//type=*main.test
ssss := ss.Elem()//type=main.I
sssss := ssss.Elem()//type=main.test
ssssss := sss.Elem()//type=main.test
fmt.Println(s.Type(), ss.Type(), sss.Type(), ssss.Type(), sssss.Type(), ssssss.Type(), v.Type(), vv.Type(), vvv.Type(), vvvv.Type(), n, nn)
}
//输出结果 main.test *main.I *main.test main.I main.test main.test main.test *main.test main.test main.test 0xc0820082c8 0x1
- Elem对于interface和指针才可使用,分别返回interface存储的内容和指针指向的内容