Golang map之needkeyupdate函数详解

定义和实现

@(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可能与内存管理有关,后续再详细说明。

猜你喜欢

转载自blog.csdn.net/fengshenyun/article/details/100713154
今日推荐