[golang] for ループの一時変数はそれぞれ別のメモリ領域(アドレス)に配置される

# 目的
for ループの一時変数はそれぞれ別のメモリ領域(アドレス)に配置されることを知る。

これは、v1.22 で導入された仕様です。

https://go.dev/doc/go1.22#:~:text=Changes%20to%20the%20language%C2%B6

# 一応インストール手順
```
$ sudo rm -rf /usr/local/go
$ wget https://go.dev/dl/go1.21.0.linux-amd64.tar.gz
$ sudo tar -C /usr/local -xzf go1.21.0.linux-amd64.tar.gz
$ rm -rf go1.21.0.linux-amd64.tar.gz
```
```
$ echo "export PATH=\$PATH:/usr/local/go/bin/:\$HOME/go/bin" >> $HOME/.bashrc
$ source $HOME/.bashrc
```
```
~/praprago$ go mod init github.com/XXX/praprago
```
``` go.mod
module github.com/XXX/praprago

go 1.21.0

```
```
$ go version && go env GOROOT && go env GOPATH
go version go1.21.0 linux/amd64
/usr/local/go
/home/ubuntu/go
```

# 検証
## (1)
``` main.go
package main

import "fmt"

// go run .
func main() {
	fmt.Println(" ================================================================= (1)")
	PraFor1()
}

```
``` pra_for.go
package main

import (
	"fmt"
)

type MyStruct struct {
	Name string
	Age  int
}

// ////////////////////////////////////////////////////
// //////////////////////////////////////////////////// (1)
func PraFor1() {
	store := make(map[int]*MyStruct)
	// var store map[int]*MyStruct // これだと store[i] = &v の部分でエラーになる。

	myStructs := []MyStruct{
		{"AAA", 1},
		{"BBB", 2},
		{"CCC", 3},
	}
	for i, v := range myStructs {
		fmt.Println("BBBBBBBBBB_222333")
		fmt.Println("i:", i)
		fmt.Println("v:", v)
		fmt.Printf("&v: %p\n", &v)
		store[i] = &v
	}
	fmt.Println("AAAAAAAAAA_111222")
	fmt.Println("store:", store)
	fmt.Printf("store[0]: %p\n", store[0])
	fmt.Printf("*store[1]: %v\n", *store[0])
	fmt.Printf("store[1]: %p\n", store[1])
	fmt.Printf("*store[1]: %v\n", *store[1])
	fmt.Printf("store[2]: %p\n", store[2])
	fmt.Printf("*store[2]: %v\n", *store[2])
}

```

### v1.22 以前(検証環境は V1.21.0)
```
~/praprago$ go run .
 ================================================================= (1)
BBBBBBBBBB_222333
i: 0
v: {AAA 1}
&v: 0xc000010018
BBBBBBBBBB_222333
i: 1
v: {BBB 2}
&v: 0xc000010018
BBBBBBBBBB_222333
i: 2
v: {CCC 3}
&v: 0xc000010018
AAAAAAAAAA_111222
store: map[0:0xc000010018 1:0xc000010018 2:0xc000010018]
store[0]: 0xc000010018
*store[1]: {CCC 3}
store[1]: 0xc000010018
*store[1]: {CCC 3}
store[2]: 0xc000010018
*store[2]: {CCC 3}
```

### v1.22 以降(検証環境は V1.23.2 )
```
~/praprago$ go run .
 ================================================================= (1)
BBBBBBBBBB_222333
i: 0
v: {AAA 1}
&v: 0xc000010018
BBBBBBBBBB_222333
i: 1
v: {BBB 2}
&v: 0xc000010048
BBBBBBBBBB_222333
i: 2
v: {CCC 3}
&v: 0xc000010078
AAAAAAAAAA_111222
store: map[0:0xc000010018 1:0xc000010048 2:0xc000010078]
store[0]: 0xc000010018
*store[1]: {AAA 1}
store[1]: 0xc000010048
*store[1]: {BBB 2}
store[2]: 0xc000010078
*store[2]: {CCC 3}
```

## (2)
```
~/praprago$ tree -La 3 -I .git
.
├── go.mod
└── main.go

1 directory, 2 files
```
``` main.go
package main

import "fmt"

func main() {
	numGoroutines := 5

	done := make(chan bool, numGoroutines)

	for i := 0; i < numGoroutines; i++ {
		go func() {
			fmt.Printf("goroutine %d is running\n", i)
			done <- true
		}()
	}
	for i := 0; i < numGoroutines; i++ {
		<-done
	}

	fmt.Println("All goroutines finished")
}

```
### v1.22 以前(検証環境は V1.21.0)
それぞれのループの `i` はアドレスが同じなので、仮に、`i = 1` で呼ばれている groutine でも、実際に`i`を参照するタイミングで、次のループに進んで`i`が増えていたら、その瞬間の `i`を使うことになる。

下記を見ると、いずれのgroroutine の開始前に全てのループが終了し、全ての goroutine はループ終了後の `i` を使うことになる。
```
~/praprago$ go run main.go
goroutine 5 is running
goroutine 5 is running
goroutine 5 is running
goroutine 5 is running
goroutine 5 is running
All goroutines finished
```

### v1.22 以降(検証環境は V1.23.2 )
```
~/praprago$ go run main.go
goroutine 4 is running
goroutine 0 is running
goroutine 1 is running
goroutine 2 is running
goroutine 3 is running
All goroutines finished
```

# 参考

https://www.amazon.co.jp/-/en/Teiva-Harsanyi/dp/4295017531