目的
map のループの途中で、新しいキーが挿入されたときの挙動を理解する。
結論
map のループの途中で新しいキーが挿入されると、予測不可能な挙動を起こす。
検証
~/praprago$ go version
go version go1.23.2 linux/amd64
main.go
package main
import "fmt"
// go run .
func main() {
fmt.Println(" ================================================================= (1)")
PraFor1()
fmt.Println(" ================================================================= (2)")
PraFor2()
}
pra_for.go
package main
import (
"fmt"
"time"
)
// ////////////////////////////////////////////////////
// //////////////////////////////////////////////////// (1)
// range では、for ループ全体の開始前に一回だけ評価されて、一時変数にコピーが代入される。
// ゆえに、myslice に要素が追加されても、for ループには全く影響を及ぼさない。
func PraFor1() {
myslice := []int{1, 2, 3, 4, 5}
go func() {
for i := 0; i < 16; i++ {
myslice = append(myslice, i+1000)
fmt.Println("Appended to myslice:", i+1000)
time.Sleep(200 * time.Millisecond)
}
}()
for i, v := range myslice {
fmt.Println("index:", i, "value:", v)
time.Sleep(1000 * time.Millisecond)
}
}
// ////////////////////////////////////////////////////
// //////////////////////////////////////////////////// (2)
// 「range では、for ループ全体の開始前に一回だけ評価されて、一時変数にコピーが代入される」という説明をしたが、map は例外である。
// map への要素追加は、予測不可能な結果をもたらす。
//
// また、map は順序が不定である。
func PraFor2() {
mymap := map[int]string{1: "aaa", 2: "bbb", 3: "ccc"}
go func() {
for i := 0; i < 100; i++ {
mymap[i+1000] = fmt.Sprintf("new%d", i+1000)
fmt.Println("Added to mymap:", i+1000)
time.Sleep(300 * time.Millisecond)
}
}()
for k, v := range mymap {
fmt.Println("key:", k, "value:", v)
time.Sleep(1000 * time.Millisecond)
}
}
一回目
~/praprago$ go run .
================================================================= (1)
index: 0 value: 1
Appended to myslice: 1000
Appended to myslice: 1001
Appended to myslice: 1002
Appended to myslice: 1003
Appended to myslice: 1004
index: 1 value: 2
Appended to myslice: 1005
Appended to myslice: 1006
Appended to myslice: 1007
Appended to myslice: 1008
Appended to myslice: 1009
index: 2 value: 3
Appended to myslice: 1010
Appended to myslice: 1011
Appended to myslice: 1012
Appended to myslice: 1013
Appended to myslice: 1014
index: 3 value: 4
Appended to myslice: 1015
index: 4 value: 5
================================================================= (2)
key: 1 value: aaa
Added to mymap: 1000
Added to mymap: 1001
Added to mymap: 1002
Added to mymap: 1003
key: 2 value: bbb
Added to mymap: 1004
Added to mymap: 1005
Added to mymap: 1006
key: 3 value: ccc
Added to mymap: 1007
Added to mymap: 1008
Added to mymap: 1009
key: 1000 value: new1000
Added to mymap: 1010
Added to mymap: 1011
Added to mymap: 1012
Added to mymap: 1013
二回目
~/praprago$ go run .
================================================================= (1)
index: 0 value: 1
Appended to myslice: 1000
Appended to myslice: 1001
Appended to myslice: 1002
Appended to myslice: 1003
Appended to myslice: 1004
index: 1 value: 2
Appended to myslice: 1005
Appended to myslice: 1006
Appended to myslice: 1007
Appended to myslice: 1008
Appended to myslice: 1009
index: 2 value: 3
Appended to myslice: 1010
Appended to myslice: 1011
Appended to myslice: 1012
Appended to myslice: 1013
Appended to myslice: 1014
index: 3 value: 4
Appended to myslice: 1015
index: 4 value: 5
================================================================= (2)
key: 1 value: aaa
Added to mymap: 1000
Added to mymap: 1001
Added to mymap: 1002
Added to mymap: 1003
key: 2 value: bbb
Added to mymap: 1004
Added to mymap: 1005
Added to mymap: 1006
key: 3 value: ccc
Added to mymap: 1007
Added to mymap: 1008
Added to mymap: 1009
三回目
~/praprago$ go run .
================================================================= (1)
index: 0 value: 1
Appended to myslice: 1000
Appended to myslice: 1001
Appended to myslice: 1002
Appended to myslice: 1003
Appended to myslice: 1004
index: 1 value: 2
Appended to myslice: 1005
Appended to myslice: 1006
Appended to myslice: 1007
Appended to myslice: 1008
Appended to myslice: 1009
index: 2 value: 3
Appended to myslice: 1010
Appended to myslice: 1011
Appended to myslice: 1012
Appended to myslice: 1013
Appended to myslice: 1014
index: 3 value: 4
Appended to myslice: 1015
index: 4 value: 5
================================================================= (2)
key: 1 value: aaa
Added to mymap: 1000
Added to mymap: 1001
Added to mymap: 1002
Added to mymap: 1003
key: 2 value: bbb
Added to mymap: 1004
Added to mymap: 1005
Added to mymap: 1006
key: 3 value: ccc
Added to mymap: 1007
Added to mymap: 1008
Added to mymap: 1009
key: 1000 value: new1000
Added to mymap: 1010
Added to mymap: 1011
Added to mymap: 1012
Added to mymap: 1013
key: 1001 value: new1001
Added to mymap: 1014
Added to mymap: 1015
Added to mymap: 1016
key: 1002 value: new1002
Added to mymap: 1017
Added to mymap: 1018
Added to mymap: 1019
key: 1003 value: new1003
Added to mymap: 1020
Added to mymap: 1021
Added to mymap: 1022
Added to mymap: 1023
四回目
~/praprago$ go run .
================================================================= (1)
index: 0 value: 1
Appended to myslice: 1000
Appended to myslice: 1001
Appended to myslice: 1002
Appended to myslice: 1003
Appended to myslice: 1004
index: 1 value: 2
Appended to myslice: 1005
Appended to myslice: 1006
Appended to myslice: 1007
Appended to myslice: 1008
Appended to myslice: 1009
index: 2 value: 3
Appended to myslice: 1010
Appended to myslice: 1011
Appended to myslice: 1012
Appended to myslice: 1013
Appended to myslice: 1014
index: 3 value: 4
Appended to myslice: 1015
index: 4 value: 5
================================================================= (2)
key: 1 value: aaa
Added to mymap: 1000
Added to mymap: 1001
Added to mymap: 1002
Added to mymap: 1003
key: 2 value: bbb
Added to mymap: 1004
Added to mymap: 1005
Added to mymap: 1006
key: 3 value: ccc
Added to mymap: 1007
Added to mymap: 1008
Added to mymap: 1009
key: 1000 value: new1000
Added to mymap: 1010
Added to mymap: 1011
Added to mymap: 1012
Added to mymap: 1013
key: 1001 value: new1001
Added to mymap: 1014
Added to mymap: 1015
Added to mymap: 1016
key: 1002 value: new1002
Added to mymap: 1017
Added to mymap: 1018
Added to mymap: 1019
key: 1003 value: new1003
Added to mymap: 1020
Added to mymap: 1021
Added to mymap: 1022
Added to mymap: 1023
key: 1004 value: new1004
Added to mymap: 1024
Added to mymap: 1025
Added to mymap: 1026
参考