回答編集履歴
3
解説の修正
test
CHANGED
@@ -28,7 +28,7 @@
|
|
28
28
|
```
|
29
29
|
|
30
30
|
型宣言だけだと、buckets==nilです。bucketsポインタの指す先に別のメモリがあてがわれて初めてmap型として機能します。
|
31
|
-
「
|
31
|
+
「bucketsポインタの指す先に別のメモリをあてる」のがmakeやリテラルなどを記述する方法です。
|
32
32
|
```go
|
33
33
|
m1 := map[string]int{}
|
34
34
|
m2 := make(map[string]int)
|
2
mapの実体についての修正
test
CHANGED
@@ -8,23 +8,26 @@
|
|
8
8
|
|
9
9
|
map型の内部表現
|
10
10
|
|
11
|
-
https://github.com/golang/go/blob/
|
11
|
+
https://github.com/golang/go/blob/2580d0e08d5e9f979b943758d3c49877fb2324cb/src/runtime/map.go#L116-L130
|
12
12
|
```go
|
13
|
-
type map
|
13
|
+
type hmap struct {
|
14
|
-
typ _type
|
15
|
-
key *_type
|
16
|
-
elem *_type
|
17
|
-
|
14
|
+
// Note: the format of the hmap is also encoded in cmd/compile/internal/reflectdata/reflect.go.
|
18
|
-
//
|
15
|
+
// Make sure this stays in sync with the compiler's definition.
|
19
|
-
hasher func(unsafe.Pointer, uintptr) uintptr
|
20
|
-
|
16
|
+
count int // # live cells == size of map. Must be first (used by len() builtin)
|
21
|
-
elemsize uint8 // size of elem slot
|
22
|
-
bucketsize uint16 // size of bucket
|
23
|
-
flags
|
17
|
+
flags uint8
|
18
|
+
B uint8 // log_2 of # of buckets (can hold up to loadFactor * 2^B items)
|
19
|
+
noverflow uint16 // approximate number of overflow buckets; see incrnoverflow for details
|
20
|
+
hash0 uint32 // hash seed
|
21
|
+
|
22
|
+
buckets unsafe.Pointer // array of 2^B Buckets. may be nil if count==0.
|
23
|
+
oldbuckets unsafe.Pointer // previous bucket array of half the size, non-nil only when growing
|
24
|
+
nevacuate uintptr // progress counter for evacuation (buckets less than this have been evacuated)
|
25
|
+
|
26
|
+
extra *mapextra // optional fields
|
24
27
|
}
|
25
28
|
```
|
26
29
|
|
27
|
-
型宣言
|
30
|
+
型宣言だけだと、buckets==nilです。bucketsポインタの指す先に別のメモリがあてがわれて初めてmap型として機能します。
|
28
31
|
「key、elem、bucketポインタの指す先に別のメモリをあてる」のがmakeやリテラルなどを記述する方法です。
|
29
32
|
```go
|
30
33
|
m1 := map[string]int{}
|
1
まとめ追記
test
CHANGED
@@ -43,3 +43,6 @@
|
|
43
43
|
}
|
44
44
|
```
|
45
45
|
strポインタの指す先に文字列データが格納されている必要がありますが、こちらは「文字列値」そのものがコード中にあるのでそれをコンパイラはプログラムコードに埋め込み、そこへのポインタや長さが最初から算出可能なのでstrもlenもコンパイル時点で初期値を与えられます。
|
46
|
+
|
47
|
+
つまり、文字列もスライスもマップも宣言に関する情報を持つ構造体があり、実データは別途メモリ確保してそのポインタを構造体が持っているという形です。
|
48
|
+
実データ用に別途初期化処理にてメモリ割り当てが必要です。それを行うのがmake関数やリテラル初期化による記述ということです。
|