Go Range (Japanese)

"Range" from golang wiki

Go公式WikiのRangeの日本語意訳になります。
(元記事の最終更新日: 2015/11/21 rev.4)

ループで使用するレンジ節(range)についての例が載っています。


レンジ節

概要

レンジ節は、配列・スライス・文字列・マップ・チャネルに対してイテレートする方法を提供します。

for k, v := range myMap {
	log.Printf("key=%v, value=%v", k, v)
}

for v := range myChannel {
	log.Printf("value=%v", v)
}

for i, v := range myArray {
	log.Printf("%d の配列の値は %v", i, v)
}

参考

もしレンジ式の左辺で一つの値しか使用していない場合、以下のテーブルでは1番目の値となります。

レンジ式 1番目の値 2番目の値(オプション) 備考
配列またはスライス [n]E, *[n]E, []E インデックス i int a[i] E
文字列型 インデックス i int ルーン型 int バイトではなくユニコードのコードポイントを繰り返し処理する
マップ m map[K]V キー k K m[k] V
チャネル c chan E 要素 e E なし

訳注: 上記テーブルの列は以下を参照してください

// 以下の `range E` が「レンジ式」, kが「1番目の値」, vが「2番目の値」になります
for k, v := range E {
    // ...
}

落とし穴

スライスやマップの値に対して繰り返し処理をする際は、以下のようにするかもしれません。

items := make([]map[int]int, 10)
for _, item := range items {
	item = make(map[int]int, 1) // おっと! itemはスライスの要素のただのコピーです.
	item[1] = 2                 // この'item'は次のイテレーションでは失われるでしょう.
}

makeと代入はうまく動作するように見えます。
しかしレンジの値のプロパティ(上記ではitemとして格納されています)はitemsからの値のコピーです。itemsの中の値へのポインタではありません。
次のコードはうまく動作します。

items := make([]map[int]int, 10)
for i := range items {
	items[i] = make(map[int]int, 1)
	items[i][1] = 2
}
 
comments powered by Disqus