rangeで走査する
添字と値を同時に受け取る
Go
for i, price := range prices {
fmt.Println(i, price)
}1つ目が添字、2つ目が値です。ここまで書いてきた形と比べます。
Go
for i := 0; i < len(prices); i++ {
price := prices[i]
}
for i, price := range prices { // 同じこと
}短いだけではありません。範囲を超える書き間違いが起こりえません。 i <= len(prices) と書いて止まる事故が、この形なら発生しません。
実際の Go のコードでは、並びを回すときほぼ range を使います。
片方だけ要るとき
値だけでよいなら、添字を _ にします。
Go
for _, price := range prices {
total += price
}添字だけでよいなら、値を書かずに済みます。
Go
for i := range prices {
fmt.Println(i)
}2つ目を省略できるのは、要らないものを書かせないためです。_ すら書かなくてよくなります。
値はコピーである
ここが唯一の落とし穴です。range が渡してくるのは値のコピーです。
Go
for _, price := range prices {
price = 0 // コピーを変えただけ
}
fmt.Println(prices) // 元のまま書き換えたいなら、添字を使います。
Go
for i := range prices {
prices[i] = 0 // これなら効く
}第6章で構造体を扱うようになると、この違いが効いてきます。「range で回して中身を書き換えたのに反映されない」は定番の詰まりどころです。
文字列にも使える
Go
for i, r := range "きのこ" {
fmt.Println(i, string(r))
}プレーンテキスト
0 き
3 の
6 こ添字が 0・3・6 と飛んでいます。日本語の1文字が3バイトを使うためです。range は文字の単位で回してくれるので、日本語を1文字ずつ扱うときはこの形が安全です。
添字で s[0] のように取り出すと、バイト単位になって文字が壊れます。日本語を扱うときに覚えておく価値のある違いです。
要件
for i, name := range namesの形で回す- 番号は1から始める
N. 商品名 価格円の形で1行ずつ並べる- 行の区切りは
\n。最後に余分な改行を付けない
入出力例
rangeList(["きのこ図鑑","中古スマホ"], [1200,24800]) → "1. きのこ図鑑 1200円
2. 中古スマホ 24800円"
rangeList(["きのこ図鑑"], [1200]) → "1. きのこ図鑑 1200円"
rangeList(["A","B","C"], [100,200,300]) → "1. A 100円
2. B 200円
3. C 300円"ヒント
編集 ゆめさく編集部