こんにちは、かつコーチです。
「Goでループを書きたいのに、whileって書いてもエラーになる」。
他の言語からGoに入った人が、最初につまずくポイントの一つです。
実はGoには繰り返し構文がforしかありません。
この記事では、なぜGoがforだけに絞っているのか、そしてforの複数の書き方を初心者向けに解説します。
読み終える頃には、条件だけのループも無限ループも、自信を持って書けるようになります。
Goのfor文とは?
Goには繰り返し構文がforしかない
多くの言語にはforとwhileの両方が用意されています。
たとえばJavaScriptやJavaでは、条件だけで繰り返したいときにwhileを使います。
ところがGoにはwhileというキーワード自体が存在しません。
繰り返し処理はすべてfor文(同じ処理を条件が満たされる間くり返す構文)で書きます。
なぜGoはforだけに絞ったのか
Go言語の設計者は、シンプルさを重視して言語仕様を作りました。
繰り返しの構文がforとwhileの2つあると、書き方に迷いが生まれます。
「ここはwhileっぽいからwhile」「ここはカウンタがあるからfor」。
こうした使い分けの判断が、人によってブレてしまうためです。
Goはfor1つに統一することで、コードの書き方に個人差が出にくいようにしています。
これはgofmt(全員が同じフォーマットで書けるようにする社内の文書テンプレートのような仕組み)にも通じる、Goらしい思想です。
基本の書き方
手順1:他言語のfor文と同じ書き方
まずは馴染みのある書き方から見てみましょう。
package main
import "fmt"
func main() {
for i := 0; i < 5; i++ {
fmt.Println(i)
}
}
i := 0(初期化)、i < 5(継続条件)、i++(更新処理)の3つをセミコロンで区切る書き方です。
C言語やJavaのfor文を書いたことがある人には、見慣れた形だと思います。
手順2:while相当の書き方(条件式のみ)
Goでは、初期化と更新処理を省略して、条件式だけを書くこともできます。
これが他言語のwhileに相当する書き方です。
package main
import "fmt"
func main() {
count := 0
for count < 3 {
fmt.Println("カウント:", count)
count++
}
}
セミコロンを使わず、条件式だけを書けば、それがそのままwhileの役割を果たします。
「Goにwhileがない」と言われるのは、この書き方がfor一つでまかなえてしまうからです。
手順3:無限ループの書き方
条件式すら省略すると、無限に繰り返す無限ループ(終了条件を書かず、ずっと処理を繰り返すループ)になります。
package main
import "fmt"
func main() {
i := 0
for {
if i >= 3 {
break
}
fmt.Println("無限ループ内:", i)
i++
}
}
break(ループを途中で抜け出す命令)を使って、条件を満たしたら自分でループを止める書き方です。
サーバーのように「動き続けること」が前提の処理でよく使われます。
手順4:rangeを使った書き方
配列やスライス、マップなどを順番に処理したいときは、rangeというキーワードを使います。
package main
import "fmt"
func main() {
fruits := []string{"りんご", "みかん", "ぶどう"}
for index, fruit := range fruits {
fmt.Println(index, fruit)
}
}
rangeは「要素のインデックス」と「値」を1つずつ取り出してくれます。
配列やスライスについては、次の記事「配列とスライスの違い・使い方」で詳しく解説します。
つまずきやすい設定・注意点
forの3つの要素(初期化・条件・更新処理)は、それぞれ省略が可能です。
ただし省略するときはセミコロンの数に注意が必要です。
条件式だけを書くときはセミコロンを一切使わず、for 条件式 {}という形にします。
セミコロンを1つでも余分に書くと、コンパイルエラーになるので気をつけてください。
よくあるつまずきポイント・エラー対処
while構文をそのまま書いてしまうケース
私が実際にGoを書き始めたころ、他の言語の癖でうっかりwhileを書いてしまったことがあります。
❌Before:JavaScript感覚でwhileを書く
package main
import "fmt"
func main() {
i := 0
while i < 5 {
fmt.Println(i)
i++
}
}
これをgo run main.goで実行すると、次のようなエラーが出ました。
./main.go:7:8: syntax error: unexpected name i, expected {
Goのパーサーはwhileという単語を知らないため、whileを関数名か何かの識別子として扱おうとします。
その結果、次に続くiの位置で構文が崩れてしまい、分かりにくいエラーメッセージになるのです。
最初は「え、iのどこが悪いの?」と数分悩んでしまいました。
✅After:条件式だけのfor文に書き換える
package main
import "fmt"
func main() {
i := 0
for i < 5 {
fmt.Println(i)
i++
}
}
whileをforに書き換えるだけで、意図通りに動きます。
Goで謎の構文エラーが出たときは、まず「while、do-whileなど他言語のキーワードを紛れ込ませていないか」を疑うと解決が早いです。
応用・一歩先の使い方
forはcontinue(今回の繰り返しだけスキップして次に進む命令)と組み合わせることもできます。
package main
import "fmt"
func main() {
for i := 1; i <= 10; i++ {
if i%2 != 0 {
continue
}
fmt.Println("偶数:", i)
}
}
奇数のときはcontinueで処理をスキップし、偶数のときだけ表示しています。
また、ネスト(入れ子)したforから一気に抜けたいときは、ラベル付きbreakという書き方もあります。
中級者になったら、こうした制御構文の組み合わせも覚えておくと、コードの見通しがよくなります。
まとめ
この記事のポイント
- Goには繰り返し構文が
forしかなく、whileというキーワードは存在しない - 条件式だけを書けば、他言語の
whileと同じ動きになる - 条件式すら省略すると無限ループになり、
breakで止める rangeを使うと配列やスライス、マップを順番に処理できるwhileをそのまま書くとsyntax errorになるので注意する
次に読むべき記事
forの書き方が分かったら、次はループでよく一緒に使う「配列とスライスの違い・使い方」に進みましょう。
Goの繰り返し処理の理解がさらに深まります。
タグ: Go, 初心者向け, 基本文法