在看golang源码时,有时会判断变量类型是否为kindNoPointers,然后根据判断做出一些处理,那kindNoPointers究竟表示什么意思呢?
定义
@(src\runtime\typekind.go:37)
kindNoPointers = 1 << 7
注,在源码中多个文件都有定义kindNoPointers,但没关系,值都是1 << 7
从字面上看,这个标志用来表示类型是否含有指针,事实上也确实如此,看源码:
@(src/cmd/compile/internal/gc/reflect.go:887)
func dcommontype(lsym *obj.LSym, t *types.Type) int {
...
if !types.Haspointers(t) {
i |= objabi.KindNoPointers
}
...
}
编译器会对判断每个类型是否含有指针,没有就置KindNoPointers。具体判断是否含有指针代码如下:
@(src/cmd/compile/internal/types/type.go:887)
func Haspointers(t *Type) bool {
return Haspointers1(t, false)
}
func Haspointers1(t *Type, ignoreNotInHeap bool) bool {
switch t.Etype {
case TINT, TUINT, TINT8, TUINT8, TINT16, TUINT16, TINT32, TUINT32, TINT64,
TUINT64, TUINTPTR, TFLOAT32, TFLOAT64, TCOMPLEX64, TCOMPLEX128, TBOOL, TSSA:
return false
case TARRAY:
if t.NumElem() == 0 { // empty array has no pointers
return false
}
return Haspointers1(t.Elem(), ignoreNotInHeap)
case TSTRUCT:
for _, t1 := range t.Fields().Slice() {
if Haspointers1(t1.Type, ignoreNotInHeap) {
return true
}
}
return false
case TPTR, TSLICE:
return !(ignoreNotInHeap && t.Elem().NotInHeap())
case TTUPLE:
ttup := t.Extra.(*Tuple)
return Haspointers1(ttup.first, ignoreNotInHeap) || Haspointers1(ttup.second, ignoreNotInHeap)
}
return true
}
代码不多,可简单总结下:
- 当类型为TINT, TUINT, TINT8, TUINT8, TINT16, TUINT16, TINT32, TUINT32, TINT64,TUINT64, TUINTPTR, TFLOAT32, TFLOAT64, TCOMPLEX64, TCOMPLEX128, TBOOL, TSSA时,kindNoPointers为true。
- 当TARRAY、TSTRUCT里面的包含的类型都是kindNoPointers,则这个TARRAY、TSTRUCT为kindNoPointers。
- 当类型为TPTR、TSLICE时,kindNoPointers为true。
- 当类型为TTUPLE时,当tuple里面的两个元素都为kindNoPointers时,则tuple为kindNoPointers。
在Go里面好像没有看到过tuple类型,估计是内部用的,没有开放出来