type maptype struct

  1. maptype 是 map 的元类型结构体。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
type maptype struct {
    typ    _type    // map类型
    key    *_type   // key类型
    elem   *_type   // elem类型
    
    // 桶的类型,桶包含tophashs、keys、elems、overflow这四块
    // 由于key/elem是不确定的类型,所以bucket也是不同的类型
    // bucket是否包含指针类型,是取决于该结构中是否存在指针
    //	1. tophashs 是非指针
    //  2. keys、elems 是根据具体情况的
    //  3. overflow 是个指针,那么是否意味则bucket是否包含指针类型?
    // 其实bucket是否包含指针类型是根据keys、elems决定的
    // bucket 的组成由 tophash、keys、elems、overflow
    bucket *_type // internal type representing a hash bucket
    // function for hashing keys (ptr to key, seed) -> hash
    // hash函数,用于(key, h.hash0)
    hasher     func(unsafe.Pointer, uintptr) uintptr	
    keysize    uint8  // size of key slot   // key值大小
    elemsize   uint8  // size of elem slot  // value值大小
    bucketsize uint16 // size of bucket     // 桶大小
    flags      uint32 // map的标志位
}

自定义map类型

1
2
3
4
type u struct {
    maptype
    u uncommontype
}
  1. maptype的组成,以及maptype.bucket的组成。
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
package main

import (
    "fmt"
    "unsafe"
)

type tpe struct {
    size       uintptr
    ptrdata    uintptr // size of memory prefix holding all pointers
    hash       uint32
    tflag      uint8
    align      uint8
    fieldAlign uint8
    kind       uint8
    // function for comparing objects of this type
    // (ptr to object A, ptr to object B) -> ==?
    equal func(unsafe.Pointer, unsafe.Pointer) bool
    // gcdata stores the GC type data for the garbage collector.
    // If the KindGCProg bit is set in kind, gcdata is a GC program.
    // Otherwise it is a ptrmask bitmap. See mbitmap.go for details.
    gcdata    *byte
    str       int32
    ptrToThis int32
}

type maptype struct {
    typ  tpe  // map类型
    key  *tpe // key类型
    elem *tpe // elem类型

    // 桶的类型,桶包含tophashs、keys、elems、overflow这四块
    // 由于key/elem是不确定的类型,所以bucket也是不同的类型
    // bucket是否包含指针类型,是取决于该结构中是否存在指针
    //	1. tophashs 是非指针
    //  2. keys、elems 是根据具体情况的
    //  3. overflow 是个指针,那么是否意味则bucket是否包含指针类型?
    // 其实bucket是否包含指针类型是根据keys、elems决定的
    bucket *tpe // internal type representing a hash bucket
    // function for hashing keys (ptr to key, seed) -> hash
    // hash函数,用于(key, h.hash0)
    hasher     func(unsafe.Pointer, uintptr) uintptr
    keysize    uint8  // size of key slot	// key值大小
    elemsize   uint8  // size of elem slot	// value值大小
    bucketsize uint16 // size of bucket		// 桶大小
    flags      uint32 // map的标志位
}

type e struct {
    i *tpe
    d uintptr
}

func main() {
    m := make(map[string]uint8, 8)

    var d any = m
    dd1 := **(**maptype)(unsafe.Pointer(&d))
    dd := *(**(**maptype)(unsafe.Pointer(&d))).bucket

    // 8 + 16*8 + 8 + 8
    // 8 + 128 + 8 + 8
    // 98 -> 152

    fmt.Printf("%#v\n", dd1)
    fmt.Printf("%#v\n", dd)

    // Output:
    // main.maptype{
    //  typ:main.tpe{
    //      size:0x8,
    //      ptrdata:0x8,
    //      hash:0xfc5c9caf,
    //      tflag:0x2,
    //      align:0x8,
    //      fieldAlign:0x8,
    //      kind:0x35,          // 0x35 = 53 = 32 + 21
    //      equal:(func(unsafe.Pointer, unsafe.Pointer) bool)(nil),
    //      gcdata:(*uint8)(0x71b448),
    //      str:13639,
    //      ptrToThis:0
    //  },
    //  key:(*main.tpe)(0x6e8140),
    //  elem:(*main.tpe)(0x6e82c0),
    //  bucket:(*main.tpe)(0x6f1d40),
    //  hasher:(func(unsafe.Pointer, uintptr) uintptr)(0x6adf40),
    //  keysize:0x10,       // string 大小 16 byte
    //  elemsize:0x1,       // uint8 大小 1 byte
    //  bucketsize:0x98,    // 桶大小 tophash + 8key + 8elem + 1overflow
    //  flags:0xc
    //}
    //
    // kind:0x35:32.间接存储在接口中; 21.map类型

    //main.tpe{
    //  size:0x98,
    //  ptrdata:0x98,
    //  hash:0x9f98cd28,
    //  tflag:0x2,
    //  align:0x8,
    //  fieldAlign:0x8,
    //  kind:0x19,
    //  equal:(func(unsafe.Pointer, unsafe.Pointer) bool)(nil),
    //  gcdata:(*uint8)(0x71b5f8),
    //  str:17051,
    //  ptrToThis:0
    //}
}