定义和实现
@(src/runtime/type.go:385)
func (mt *maptype) needkeyupdate() bool { // true if we need to update key on an overwrite
return mt.flags&8 != 0
}
我们先看下这个函数的使用场景,在对map做插入时,当发现插入的key已经存在时,正常流程只需要更新value的值,但当needkeyupdate函数返回为true时,还需要更新key的值,非常神奇的操作,实在没有想出有什么使用场景,直接上源码。
@(src/cmd/compile/internal/gc/reflect.go:1302)
func dtypesym(t *types.Type) *obj.LSym {
...
if needkeyupdate(t.Key()) {
flags |= 8 // need key update
}
...
}
@(src/cmd/compile/internal/gc/reflect.go:1070)
func needkeyupdate(t *types.Type) bool {
switch t.Etype {
case TBOOL, TINT, TUINT, TINT8, TUINT8, TINT16, TUINT16, TINT32, TUINT32,
TINT64, TUINT64, TUINTPTR, TPTR, TUNSAFEPTR, TCHAN:
return false
case TFLOAT32, TFLOAT64, TCOMPLEX64, TCOMPLEX128, // floats and complex can be +0/-0
TINTER,
TSTRING: // strings might have smaller backing stores
return true
case TARRAY:
return needkeyupdate(t.Elem())
case TSTRUCT:
for _, t1 := range t.Fields().Slice() {
if needkeyupdate(t1.Type) {
return true
}
}
return false
default:
Fatalf("bad type for map key: %v", t)
return true
}
}
从代码上来看,当key类型为float32\float64\complex64\complex64\interface\string,或字段里面包含这些类型的都需要更新key。float32\float64\complex64\complex64好理解,interface和string可能与内存管理有关,后续再详细说明。