func modMap(m map[int]string) { //liststart1
-
modMap
という関数を定義しています。この関数は、整数をキー、文字列を値とするマップを受け取ります。
m[2] = "こんにちは"
- マップ
m
のキー2
に対して、値"こんにちは"
を設定しています。
m[3] = "さようなら"
- マップ
m
のキー3
に対して、値"さようなら"
を設定しています。
delete(m, 1)
- マップ
m
からキー1
を削除しています。
func modSlice(s []int) {
-
modSlice
という関数を定義しています。この関数は、整数のスライスを受け取ります。
for k, v := range s {
- スライス
s
の各要素に対して、インデックスk
と値v
を取得するためのfor
ループを開始しています。
s[k] = v * 2
- スライス
s
の各要素を2倍にしています。k
はインデックスで、v
はその位置の値です。
s = append(s, 10)
- スライス
s
の末尾に10
を追加していますが、この変更は呼び出し元には反映されません。
func main() { //liststart2
- プログラムのエントリーポイントである
main
関数を定義しています。
m := map[int]string{
- 新しいマップ
m
を作成し、整数をキー、文字列を値とする初期値を設定しています。
1: "1番目",
2: "2番目",
}
- マップ
m
に2つのキーと値を追加しています。
modMap(m)
-
modMap
関数を呼び出し、マップm
を引数として渡しています。この関数内でマップが変更されます。
fmt.Println(m) // map[2:こんにちは 3:さようなら]
- 変更後のマップ
m
を出力しています。表示される内容は、map[2:こんにちは 3:さようなら]
です。
s := []int{1, 2, 3}
- 整数のスライス
s
を定義し、初期値として1, 2, 3
を設定しています。
modSlice(s)
-
modSlice
関数を呼び出し、スライスs
を引数として渡しています。この関数内でスライスが変更されますが、呼び出し元には反映されません。
fmt.Println(s) // [2 4 6]
- スライス
s
を出力していますが、呼び出し後の変更は反映されていないため、元の値[1 2 3]
が表示されるはずです。
Go言語におけるマップ(map)とスライス(slice)の値渡しについて解説します。
マップ(map)の値渡し
-
参照型:
- マップは参照型です。これは、マップの変数がマップデータの実体(メモリ内のデータ)を指し示すポインタのように動作することを意味します。
- したがって、関数にマップを渡すと、その関数内でマップの内容を変更すると、呼び出し元のマップにもその変更が反映されます。
-
例:
m := map[int]string{ 1: "1番目", 2: "2番目", } modMap(m) // modMap内での変更は呼び出し元にも影響する
この場合、
modMap
関数内でマップの要素を変更(追加や削除)すると、main
関数内のm
にもその変更が反映されます。
スライス(slice)の値渡し
-
参照型だけど再代入は不可:
- スライスも参照型です。スライス自体はデータを指し示すポインタを持っており、スライスの内容を変更することはできます。
- しかし、スライスを関数に渡し、そのスライスを再代入(新しいスライスを作成するなど)すると、呼び出し元のスライスには影響しません。
-
例:
s := []int{1, 2, 3} modSlice(s) // modSlice内での変更は呼び出し元には影響しない
この場合、
modSlice
関数内でs
の各要素を変更すること(例えば、値を2倍にすること)は可能ですが、append
で新しい要素を追加した際にs
を再代入することで新しいスライスを作成すると、呼び出し元のs
には変更が反映されません。
まとめ
-
マップ:
- 参照型であり、関数内での変更が呼び出し元に反映される。
-
スライス:
- 参照型ではあるが、スライス自体を再代入すると呼び出し元には反映されない。スライスの内容(要素)は変更可能。