代码

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)}