代码
func MapTest() { var aMap = map[int64]int64{ 1: 10, 2: 20, 3: 30, } for k, v := range aMap { fmt.Println(k, v) }}
编译
go tool compile -N -l -S ./test_map.go > ./test_map.s
汇编后果
"".MapTest STEXT size=912 args=0x0 locals=0x208 funcid=0x0 0x0000 00000 (./test_map.go:13) TEXT "".MapTest(SB), ABIInternal, $520-0 0x0000 00000 (./test_map.go:13) MOVQ (TLS), CX 0x0009 00009 (./test_map.go:13) LEAQ -392(SP), AX 0x0011 00017 (./test_map.go:13) CMPQ AX, 16(CX) 0x0015 00021 (./test_map.go:13) PCDATA $0, $-2 0x0015 00021 (./test_map.go:13) JLS 902 0x001b 00027 (./test_map.go:13) PCDATA $0, $-1 0x001b 00027 (./test_map.go:13) SUBQ $520, SP 0x0022 00034 (./test_map.go:13) MOVQ BP, 512(SP) 0x002a 00042 (./test_map.go:13) LEAQ 512(SP), BP 0x0032 00050 (./test_map.go:13) FUNCDATA $0, gclocals·3e27b3aa6b89137cce48b3379a2a6610(SB) 0x0032 00050 (./test_map.go:13) FUNCDATA $1, gclocals·4b48a54b979a44c0a517bad5b8d15a09(SB) 0x0032 00050 (./test_map.go:13) FUNCDATA $2, "".MapTest.stkobj(SB) 0x0032 00050 (./test_map.go:14) MOVQ $0, "".b+224(SP) 0x003e 00062 (./test_map.go:15) XORPS X1, X1 0x0041 00065 (./test_map.go:15) MOVUPS X1, ""..autotmp_7+368(SP) 0x0049 00073 (./test_map.go:15) MOVUPS X1, ""..autotmp_7+384(SP) 0x0051 00081 (./test_map.go:15) MOVUPS X1, ""..autotmp_7+400(SP) 0x0059 00089 (./test_map.go:15) LEAQ ""..autotmp_8+80(SP), DI 0x005e 00094 (./test_map.go:15) XORPS X0, X0 0x0061 00097 (./test_map.go:15) PCDATA $0, $-2 0x0061 00097 (./test_map.go:15) LEAQ -48(DI), DI 0x0065 00101 (./test_map.go:15) DUFFZERO $258 0x0078 00120 (./test_map.go:15) PCDATA $0, $-1 0x0078 00120 (./test_map.go:15) LEAQ ""..autotmp_7+368(SP), AX 0x0080 00128 (./test_map.go:15) MOVQ AX, ""..autotmp_9+240(SP) 0x0088 00136 (./test_map.go:15) TESTB AL, (AX) 0x008a 00138 (./test_map.go:15) LEAQ ""..autotmp_8+80(SP), AX 0x008f 00143 (./test_map.go:15) MOVQ AX, ""..autotmp_7+384(SP) 0x0097 00151 (./test_map.go:15) LEAQ ""..autotmp_7+368(SP), AX 0x009f 00159 (./test_map.go:15) MOVQ AX, ""..autotmp_10+304(SP) 0x00a7 00167 (./test_map.go:15) PCDATA $1, $1 0x00a7 00167 (./test_map.go:15) CALL runtime.fastrand(SB) 0x00ac 00172 (./test_map.go:15) MOVQ ""..autotmp_10+304(SP), AX 0x00b4 00180 (./test_map.go:15) TESTB AL, (AX) 0x00b6 00182 (./test_map.go:15) MOVL (SP), CX 0x00b9 00185 (./test_map.go:15) MOVL CX, 12(AX) 0x00bc 00188 (./test_map.go:15) LEAQ ""..autotmp_7+368(SP), AX 0x00c4 00196 (./test_map.go:15) MOVQ AX, "".aMap+232(SP) 0x00cc 00204 (./test_map.go:16) MOVQ $1, ""..autotmp_11+72(SP) 0x00d5 00213 (./test_map.go:16) MOVQ $10, ""..autotmp_12+64(SP) 0x00de 00222 (./test_map.go:16) MOVQ ""..autotmp_11+72(SP), AX 0x00e3 00227 (./test_map.go:16) MOVQ "".aMap+232(SP), CX 0x00eb 00235 (./test_map.go:16) LEAQ type.map[int64]int64(SB), DX 0x00f2 00242 (./test_map.go:16) MOVQ DX, (SP) 0x00f6 00246 (./test_map.go:16) MOVQ CX, 8(SP) 0x00fb 00251 (./test_map.go:16) MOVQ AX, 16(SP) 0x0100 00256 (./test_map.go:16) PCDATA $1, $2 0x0100 00256 (./test_map.go:16) CALL runtime.mapassign_fast64(SB) 0x0105 00261 (./test_map.go:16) MOVQ 24(SP), AX 0x010a 00266 (./test_map.go:16) MOVQ AX, ""..autotmp_13+296(SP) 0x0112 00274 (./test_map.go:16) TESTB AL, (AX) 0x0114 00276 (./test_map.go:16) MOVQ ""..autotmp_12+64(SP), CX 0x0119 00281 (./test_map.go:16) MOVQ CX, (AX) 0x011c 00284 (./test_map.go:17) MOVQ $2, ""..autotmp_11+72(SP) 0x0125 00293 (./test_map.go:17) MOVQ $20, ""..autotmp_12+64(SP) 0x012e 00302 (./test_map.go:17) MOVQ ""..autotmp_11+72(SP), AX 0x0133 00307 (./test_map.go:17) MOVQ "".aMap+232(SP), CX 0x013b 00315 (./test_map.go:17) LEAQ type.map[int64]int64(SB), DX 0x0142 00322 (./test_map.go:17) MOVQ DX, (SP) 0x0146 00326 (./test_map.go:17) MOVQ CX, 8(SP) 0x014b 00331 (./test_map.go:17) MOVQ AX, 16(SP) 0x0150 00336 (./test_map.go:17) CALL runtime.mapassign_fast64(SB) 0x0155 00341 (./test_map.go:17) MOVQ 24(SP), AX 0x015a 00346 (./test_map.go:17) MOVQ AX, ""..autotmp_14+288(SP) 0x0162 00354 (./test_map.go:17) TESTB AL, (AX) 0x0164 00356 (./test_map.go:17) MOVQ ""..autotmp_12+64(SP), CX 0x0169 00361 (./test_map.go:17) MOVQ CX, (AX) 0x016c 00364 (./test_map.go:18) MOVQ $3, ""..autotmp_11+72(SP) 0x0175 00373 (./test_map.go:18) MOVQ $30, ""..autotmp_12+64(SP) 0x017e 00382 (./test_map.go:18) MOVQ ""..autotmp_11+72(SP), AX 0x0183 00387 (./test_map.go:18) MOVQ "".aMap+232(SP), CX 0x018b 00395 (./test_map.go:18) LEAQ type.map[int64]int64(SB), DX 0x0192 00402 (./test_map.go:18) MOVQ DX, (SP) 0x0196 00406 (./test_map.go:18) MOVQ CX, 8(SP) 0x019b 00411 (./test_map.go:18) MOVQ AX, 16(SP) 0x01a0 00416 (./test_map.go:18) CALL runtime.mapassign_fast64(SB) 0x01a5 00421 (./test_map.go:18) MOVQ 24(SP), AX 0x01aa 00426 (./test_map.go:18) MOVQ AX, ""..autotmp_15+280(SP) 0x01b2 00434 (./test_map.go:18) TESTB AL, (AX) 0x01b4 00436 (./test_map.go:18) MOVQ ""..autotmp_12+64(SP), CX 0x01b9 00441 (./test_map.go:18) MOVQ CX, (AX) 0x01bc 00444 (./test_map.go:20) MOVQ "".aMap+232(SP), AX 0x01c4 00452 (./test_map.go:20) MOVQ AX, ""..autotmp_4+248(SP) 0x01cc 00460 (./test_map.go:20) LEAQ ""..autotmp_5+416(SP), DI 0x01d4 00468 (./test_map.go:20) XORPS X0, X0 0x01d7 00471 (./test_map.go:20) PCDATA $0, $-2 0x01d7 00471 (./test_map.go:20) LEAQ -32(DI), DI 0x01db 00475 (./test_map.go:20) NOP 0x01e0 00480 (./test_map.go:20) DUFFZERO $273 0x01f3 00499 (./test_map.go:20) PCDATA $0, $-1 0x01f3 00499 (./test_map.go:20) MOVQ ""..autotmp_4+248(SP), AX 0x01fb 00507 (./test_map.go:20) LEAQ type.map[int64]int64(SB), CX 0x0202 00514 (./test_map.go:20) MOVQ CX, (SP) 0x0206 00518 (./test_map.go:20) MOVQ AX, 8(SP) 0x020b 00523 (./test_map.go:20) LEAQ ""..autotmp_5+416(SP), AX 0x0213 00531 (./test_map.go:20) MOVQ AX, 16(SP) 0x0218 00536 (./test_map.go:20) PCDATA $1, $3 0x0218 00536 (./test_map.go:20) CALL runtime.mapiterinit(SB) 0x021d 00541 (./test_map.go:20) JMP 543 0x021f 00543 (./test_map.go:20) CMPQ ""..autotmp_5+416(SP), $0 0x0228 00552 (./test_map.go:20) JNE 559 0x022a 00554 (./test_map.go:20) JMP 886 0x022f 00559 (./test_map.go:20) MOVQ ""..autotmp_5+416(SP), AX 0x0237 00567 (./test_map.go:20) TESTB AL, (AX) 0x0239 00569 (./test_map.go:20) MOVQ (AX), AX 0x023c 00572 (./test_map.go:20) MOVQ AX, "".k+56(SP) 0x0241 00577 (./test_map.go:20) MOVQ ""..autotmp_5+424(SP), AX 0x0249 00585 (./test_map.go:20) TESTB AL, (AX) 0x024b 00587 (./test_map.go:20) MOVQ (AX), AX 0x024e 00590 (./test_map.go:20) MOVQ AX, "".v+48(SP) 0x0253 00595 (./test_map.go:21) XORPS X0, X0 0x0256 00598 (./test_map.go:21) MOVUPS X0, ""..autotmp_6+336(SP) 0x025e 00606 (./test_map.go:21) MOVUPS X0, ""..autotmp_6+352(SP) 0x0266 00614 (./test_map.go:21) LEAQ ""..autotmp_6+336(SP), AX 0x026e 00622 (./test_map.go:21) MOVQ AX, ""..autotmp_17+272(SP) 0x0276 00630 (./test_map.go:21) MOVQ "".k+56(SP), AX 0x027b 00635 (./test_map.go:21) MOVQ AX, (SP) 0x027f 00639 (./test_map.go:21) PCDATA $1, $4 0x027f 00639 (./test_map.go:21) NOP 0x0280 00640 (./test_map.go:21) CALL runtime.convT64(SB) 0x0285 00645 (./test_map.go:21) MOVQ 8(SP), AX 0x028a 00650 (./test_map.go:21) MOVQ AX, ""..autotmp_18+264(SP) 0x0292 00658 (./test_map.go:21) MOVQ ""..autotmp_17+272(SP), CX 0x029a 00666 (./test_map.go:21) TESTB AL, (CX) 0x029c 00668 (./test_map.go:21) LEAQ type.int64(SB), DX 0x02a3 00675 (./test_map.go:21) MOVQ DX, (CX) 0x02a6 00678 (./test_map.go:21) LEAQ 8(CX), DI 0x02aa 00682 (./test_map.go:21) PCDATA $0, $-2 0x02aa 00682 (./test_map.go:21) CMPL runtime.writeBarrier(SB), $0 0x02b1 00689 (./test_map.go:21) JEQ 696 0x02b3 00691 (./test_map.go:21) JMP 876 0x02b8 00696 (./test_map.go:21) MOVQ AX, 8(CX) 0x02bc 00700 (./test_map.go:21) JMP 702 0x02be 00702 (./test_map.go:21) PCDATA $0, $-1 0x02be 00702 (./test_map.go:21) MOVQ "".v+48(SP), AX 0x02c3 00707 (./test_map.go:21) MOVQ AX, (SP) 0x02c7 00711 (./test_map.go:21) CALL runtime.convT64(SB) 0x02cc 00716 (./test_map.go:21) MOVQ 8(SP), AX 0x02d1 00721 (./test_map.go:21) MOVQ AX, ""..autotmp_19+256(SP) 0x02d9 00729 (./test_map.go:21) MOVQ ""..autotmp_17+272(SP), CX 0x02e1 00737 (./test_map.go:21) TESTB AL, (CX) 0x02e3 00739 (./test_map.go:21) LEAQ type.int64(SB), DX 0x02ea 00746 (./test_map.go:21) MOVQ DX, 16(CX) 0x02ee 00750 (./test_map.go:21) LEAQ 24(CX), DI 0x02f2 00754 (./test_map.go:21) PCDATA $0, $-2 0x02f2 00754 (./test_map.go:21) CMPL runtime.writeBarrier(SB), $0 0x02f9 00761 (./test_map.go:21) JEQ 765 0x02fb 00763 (./test_map.go:21) JMP 869 0x02fd 00765 (./test_map.go:21) MOVQ AX, 24(CX) 0x0301 00769 (./test_map.go:21) JMP 771 0x0303 00771 (./test_map.go:21) PCDATA $0, $-1 0x0303 00771 (./test_map.go:21) MOVQ ""..autotmp_17+272(SP), AX 0x030b 00779 (./test_map.go:21) TESTB AL, (AX) 0x030d 00781 (./test_map.go:21) JMP 783 0x030f 00783 (./test_map.go:21) MOVQ AX, ""..autotmp_16+312(SP) 0x0317 00791 (./test_map.go:21) MOVQ $2, ""..autotmp_16+320(SP) 0x0323 00803 (./test_map.go:21) MOVQ $2, ""..autotmp_16+328(SP) 0x032f 00815 (./test_map.go:21) MOVQ AX, (SP) 0x0333 00819 (./test_map.go:21) MOVQ $2, 8(SP) 0x033c 00828 (./test_map.go:21) MOVQ $2, 16(SP) 0x0345 00837 (./test_map.go:21) PCDATA $1, $3 0x0345 00837 (./test_map.go:21) CALL fmt.Println(SB) 0x034a 00842 (./test_map.go:21) JMP 844 0x034c 00844 (./test_map.go:20) LEAQ ""..autotmp_5+416(SP), AX 0x0354 00852 (./test_map.go:20) MOVQ AX, (SP) 0x0358 00856 (./test_map.go:20) CALL runtime.mapiternext(SB) 0x035d 00861 (./test_map.go:20) NOP 0x0360 00864 (./test_map.go:20) JMP 543 0x0365 00869 (./test_map.go:21) PCDATA $0, $-2 0x0365 00869 (./test_map.go:21) CALL runtime.gcWriteBarrier(SB) 0x036a 00874 (./test_map.go:21) JMP 771 0x036c 00876 (./test_map.go:21) CALL runtime.gcWriteBarrier(SB) 0x0371 00881 (./test_map.go:21) JMP 702 0x0376 00886 (./test_map.go:24) PCDATA $0, $-1 0x0376 00886 (./test_map.go:24) PCDATA $1, $-1 0x0376 00886 (./test_map.go:24) MOVQ 512(SP), BP 0x037e 00894 (./test_map.go:24) ADDQ $520, SP 0x0385 00901 (./test_map.go:24) RET 0x0386 00902 (./test_map.go:24) NOP 0x0386 00902 (./test_map.go:13) PCDATA $1, $-1 0x0386 00902 (./test_map.go:13) PCDATA $0, $-2 0x0386 00902 (./test_map.go:13) CALL runtime.morestack_noctxt(SB) 0x038b 00907 (./test_map.go:13) PCDATA $0, $-1 0x038b 00907 (./test_map.go:13) JMP 0
上面会对这段代码进行精简分段剖析
创立空字典b
0x0032 00050 (./test_map.go:14) MOVQ $0, "".b+224(SP)
只有一行,间接指向0指针
创立非空字典aMap
0x003e 00062 (./test_map.go:15) XORPS X1, X1 // X1 = (int128)00x0041 00065 (./test_map.go:15) MOVUPS X1, ""..autotmp_7+368(SP) // autotmp_7(hmap).count = (int)0 // autotmp_7(hmap).flags = (uint8)0 // autotmp_7(hmap).B = (uint8)0 // autotmp_7(hmap).noverflow = (uint16)0 // autotmp_7(hmap).hash0 = (uint32)00x0049 00073 (./test_map.go:15) MOVUPS X1, ""..autotmp_7+384(SP) // autotmp_7(hmap).buckets = (unsafe.Pointer)0 // autotmp_7(hmap).oldbuckets= (unsafe.Pointer)00x0051 00081 (./test_map.go:15) MOVUPS X1, ""..autotmp_7+400(SP) // autotmp_7(hmap).nevacuate = (uintptr)0 // autotmp_7(hmap).extra = (*mapextra)00x0059 00089 (./test_map.go:15) LEAQ ""..autotmp_8+80(SP), DI0x005e 00094 (./test_map.go:15) XORPS X0, X00x0061 00097 (./test_map.go:15) PCDATA $0, $-20x0061 00097 (./test_map.go:15) LEAQ -48(DI), DI0x0065 00101 (./test_map.go:15) DUFFZERO $2580x0078 00120 (./test_map.go:15) PCDATA $0, $-10x0078 00120 (./test_map.go:15) LEAQ ""..autotmp_7+368(SP), AX // AX = (*hmap)&autotmp_70x0080 00128 (./test_map.go:15) MOVQ AX, ""..autotmp_9+240(SP) // autotmp_9 = AX = (*hmap)&autotmp_70x0088 00136 (./test_map.go:15) TESTB AL, (AX)0x008a 00138 (./test_map.go:15) LEAQ ""..autotmp_8+80(SP), AX // AX = &autotmp_80x008f 00143 (./test_map.go:15) MOVQ AX, ""..autotmp_7+384(SP) // autotmp_7(hmap).buckets = AX = &autotmp_80x0097 00151 (./test_map.go:15) LEAQ ""..autotmp_7+368(SP), AX // AX = &autotmp_7(hmap)0x009f 00159 (./test_map.go:15) MOVQ AX, ""..autotmp_10+304(SP) // autotmp_10 = AX = &autotmp_7(hmap)0x00a7 00167 (./test_map.go:15) PCDATA $1, $10x00a7 00167 (./test_map.go:15) CALL runtime.fastrand(SB)0x00ac 00172 (./test_map.go:15) MOVQ ""..autotmp_10+304(SP), AX // AX = autotmp_10 = (*hmap)&autotmp_70x00b4 00180 (./test_map.go:15) TESTB AL, (AX)0x00b6 00182 (./test_map.go:15) MOVL (SP), CX // CX = (int32)runtime.fastrand(SB)0x00b9 00185 (./test_map.go:15) MOVL CX, 12(AX) // autotmp_7(hmap).hash0 = CX = runtime.fastrand(SB)0x00bc 00188 (./test_map.go:15) LEAQ ""..autotmp_7+368(SP), AX // AX = (*hmap)&autotmp_70x00c4 00196 (./test_map.go:15) MOVQ AX, "".aMap+232(SP) // aMap = AX = (*hmap)&autotmp_7
失去一个指针变量aMap指向*hmap
type hmap struct { // Note: the format of the hmap is also encoded in cmd/compile/internal/gc/reflect.go. // Make sure this stays in sync with the compiler's definition. count int // # live cells == size of map. Must be first (used by len() builtin) flags uint8 B uint8 // log_2 of # of buckets (can hold up to loadFactor * 2^B items) noverflow uint16 // approximate number of overflow buckets; see incrnoverflow for details hash0 uint32 // hash seed buckets unsafe.Pointer // array of 2^B Buckets. may be nil if count==0. oldbuckets unsafe.Pointer // previous bucket array of half the size, non-nil only when growing nevacuate uintptr // progress counter for evacuation (buckets less than this have been evacuated) extra *mapextra // optional fields}其中hmap.buckets = &autotmp_8hmap.hash0 = (int32)runtime.fastrand(SB)其余变量都等于0
赋值
var aMap = map[int64]int64{ 1: 10, 2: 20, 3: 30,}
有三个值别离赋值,都是一样的,这里只讲aMap[1] = 10
截取汇编:
0x00cc 00204 (./test_map.go:16) MOVQ $1, ""..autotmp_11+72(SP) // autotmp_11 = 10x00d5 00213 (./test_map.go:16) MOVQ $10, ""..autotmp_12+64(SP) // autotmp_12 = 100x00de 00222 (./test_map.go:16) MOVQ ""..autotmp_11+72(SP), AX // AX = autotmp_11 = 10x00e3 00227 (./test_map.go:16) MOVQ "".aMap+232(SP), CX // CX = aMap0x00eb 00235 (./test_map.go:16) LEAQ type.map[int64]int64(SB), DX // DX = type.map[int64]int64(SB)0x00f2 00242 (./test_map.go:16) MOVQ DX, (SP)0x00f6 00246 (./test_map.go:16) MOVQ CX, 8(SP)0x00fb 00251 (./test_map.go:16) MOVQ AX, 16(SP)0x0100 00256 (./test_map.go:16) PCDATA $1, $20x0100 00256 (./test_map.go:16) CALL runtime.mapassign_fast64(SB) // runtime.mapassign_fast64(type.map[int64]int64(SB), aMap, AX)0x0105 00261 (./test_map.go:16) MOVQ 24(SP), AX // AX = runtime.mapassign_fast640x010a 00266 (./test_map.go:16) MOVQ AX, ""..autotmp_13+296(SP) // autotmp_13 = runtime.mapassign_fast640x0112 00274 (./test_map.go:16) TESTB AL, (AX)0x0114 00276 (./test_map.go:16) MOVQ ""..autotmp_12+64(SP), CX // CX = autotmp_12 = 20x0119 00281 (./test_map.go:16) MOVQ CX, (AX) // *AX = CX = 2
其中
func mapassign_fast64(t *maptype, h *hmap, key uint64) unsafe.Pointer { if h == nil { // 空字典报错 panic(plainError("assignment to entry in nil map")) } if h.flags&hashWriting != 0 { // 写入状态 throw("concurrent map writes") } hash := t.hasher(noescape(unsafe.Pointer(&key)), uintptr(h.hash0)) // 生成哈希值 // Set hashWriting after calling t.hasher for consistency with mapassign. h.flags ^= hashWriting // 设置写入状态 if h.buckets == nil { // 生成buckets h.buckets = newobject(t.bucket) // newarray(t.bucket, 1) }again: bucket := hash & bucketMask(h.B) // 判断去那个桶 if h.growing() { // 如果在扩大桶 growWork_fast64(t, h, bucket) } b := (*bmap)(add(h.buckets, bucket*uintptr(t.bucketsize))) // 定位到相应的桶 var insertb *bmap // 最终插入到哪个桶 var inserti uintptr // 插入到桶的哪个坑(一共bucketCnt(8)个) var insertk unsafe.Pointer // 由下面计算失去的key的地位bucketloop: for { for i := uintptr(0); i < bucketCnt; i++ { if isEmpty(b.tophash[i]) { if insertb == nil { insertb = b inserti = i } if b.tophash[i] == emptyRest { // 找到最初一个空格子,跳出进行插入 break bucketloop } continue // 找到空格子然而不是最初一个,疏忽找下一个 } k := *((*uint64)(add(unsafe.Pointer(b), dataOffset+i*8))) if k != key { // 不为空,就判断下key会不会相等 continue } insertb = b inserti = i goto done // key相等,不必插入key了,间接去done,找到值插入进好了 } // 桶外面没找到 ovf := b.overflow(t) // 看看有没有溢出桶桶 if ovf == nil { // 没有,退出 break } b = ovf // 有的话,下一个桶持续找 } // Did not find mapping for key. Allocate new cell & add entry. // 如果超过装载因子,或者溢出桶数量超过最大值,则扩大桶 if !h.growing() && (overLoadFactor(h.count+1, h.B) || tooManyOverflowBuckets(h.noverflow, h.B)) { hashGrow(t, h) goto again // Growing the table invalidates everything, so try again } if insertb == nil { // 以后的桶和溢出桶都满了,则新建一个桶 insertb = h.newoverflow(t, b) inserti = 0 // not necessary, but avoids needlessly spilling inserti } // 胜利到找到了插入地位 // 插入tophash insertb.tophash[inserti&(bucketCnt-1)] = tophash(hash) // mask inserti to avoid bounds checks // 插入 key insertk = add(unsafe.Pointer(insertb), dataOffset+inserti*8) // store new key at insert position *(*uint64)(insertk) = key h.count++done: // 获取字典的值地位 elem := add(unsafe.Pointer(insertb), dataOffset+bucketCnt*8+inserti*uintptr(t.elemsize)) // 设置和查看flags if h.flags&hashWriting == 0 { throw("concurrent map writes") } h.flags &^= hashWriting return elem}
每种字典的bmap的key和value都不一样,上面是本例子的 mapint64
const bucketCnt = 8type bmap struct { tophash [bucketCnt]uint8 key [bucketCnt]int64 // int64就是map的key的类型 elem [bucketCnt]int64 // int64就是map的value的类型 overflow *bmap // 下一个溢出bmap}
遍历
func mapiterinit(t *maptype, h *hmap, it *hiter) { if unsafe.Sizeof(hiter{})/sys.PtrSize != 12 { throw("hash_iter size incorrect") // see cmd/compile/internal/gc/reflect.go } it.t = t it.h = h // grab snapshot of bucket state it.B = h.B it.buckets = h.buckets if t.bucket.ptrdata == 0 { // Allocate the current slice and remember pointers to both current and old. // This preserves all relevant overflow buckets alive even if // the table grows and/or overflow buckets are added to the table // while we are iterating. h.createOverflow() it.overflow = h.extra.overflow it.oldoverflow = h.extra.oldoverflow } // decide where to start r := uintptr(fastrand()) if h.B > 31-bucketCntBits { r += uintptr(fastrand()) << 31 } it.startBucket = r & bucketMask(h.B) it.offset = uint8(r >> h.B & (bucketCnt - 1)) // iterator state it.bucket = it.startBucket // Remember we have an iterator. // Can run concurrently with another mapiterinit(). if old := h.flags; old&(iterator|oldIterator) != iterator|oldIterator { atomic.Or8(&h.flags, iterator|oldIterator) } mapiternext(it)}