プログラミングでは、同じ処理を何度も繰り返すことがよくあります。
多くのプログラミング言語では、for
、while
、do while
など複数の繰り返し文がありますが、Go言語は違います。
Goでは、すべての繰り返し処理を「for文」1つで表現します。
しかも書き方がシンプルで読みやすいので、初心者にもやさしいのが特徴です。
この記事では、Go言語のfor文の基本的な書き方から実際の使い方、注意点まで詳しく説明します。
基本的なfor文の書き方

一番よく使う形(カウンター付き)
説明 決まった回数だけ繰り返したいときの基本的な書き方です。
基本の書き方
for 初期値; 条件; 更新 {
// 繰り返したい処理
}
例1:0から4まで表示する
package main
import "fmt"
func main() {
for i := 0; i < 5; i++ {
fmt.Println(i)
}
}
実行結果
0
1
2
3
4
例2:1から10まで表示する
for i := 1; i <= 10; i++ {
fmt.Println(i)
}
実行結果
1
2
3
4
5
6
7
8
9
10
書き方の説明
i := 0
:最初の値を設定(初期化)i < 5
:いつまで続けるかの条件i++
:1回終わるごとに何をするか(更新)
while文のような使い方
条件だけでループする
説明 Goにはwhile
文がありませんが、for文で同じことができます。
基本の書き方
for 条件 {
// 繰り返したい処理
}
例:条件が満たされるまで繰り返す
package main
import "fmt"
func main() {
i := 0
for i < 5 {
fmt.Println("現在の値:", i)
i++ // 忘れると無限ループになる!
}
}
実行結果
現在の値: 0
現在の値: 1
現在の値: 2
現在の値: 3
現在の値: 4
例:ユーザーの入力を待つ
package main
import (
"bufio"
"fmt"
"os"
"strings"
)
func main() {
reader := bufio.NewReader(os.Stdin)
for {
fmt.Print("コマンドを入力してください('quit'で終了): ")
input, _ := reader.ReadString('\n')
input = strings.TrimSpace(input)
if input == "quit" {
break
}
fmt.Println("入力されたコマンド:", input)
}
}
無限ループ

永遠に続けるループ
説明 条件を書かないと、永遠に続くループになります。サーバーやバックグラウンド処理でよく使います。
基本の書き方
for {
// 永遠に繰り返す処理
}
例:時間を表示し続ける
package main
import (
"fmt"
"time"
)
func main() {
count := 0
for {
fmt.Printf("実行回数: %d, 現在時刻: %s\n",
count, time.Now().Format("15:04:05"))
count++
time.Sleep(1 * time.Second) // 1秒待つ
if count >= 5 {
break // 5回で止める
}
}
}
実行結果
実行回数: 0, 現在時刻: 14:30:15
実行回数: 1, 現在時刻: 14:30:16
実行回数: 2, 現在時刻: 14:30:17
実行回数: 3, 現在時刻: 14:30:18
実行回数: 4, 現在時刻: 14:30:19
重要 無限ループを使うときは、必ずbreak
で抜ける条件を用意しましょう。
rangeを使った繰り返し
スライス(配列のようなもの)を処理する
説明 Goのrange
を使うと、スライスの中身を1つずつ簡単に処理できます。
基本の書き方
for インデックス, 値 := range スライス {
// 処理
}
例1:果物の名前を表示する
package main
import "fmt"
func main() {
fruits := []string{"りんご", "バナナ", "オレンジ", "ぶどう"}
for i, fruit := range fruits {
fmt.Printf("%d番目: %s\n", i, fruit)
}
}
実行結果
0番目: りんご
1番目: バナナ
2番目: オレンジ
3番目: ぶどう
例2:インデックスが不要な場合
fruits := []string{"りんご", "バナナ", "オレンジ"}
for _, fruit := range fruits {
fmt.Println("好きな果物:", fruit)
}
実行結果
好きな果物: りんご
好きな果物: バナナ
好きな果物: オレンジ
ポイント _
(アンダースコア)を使うと、使わない値を無視できます。
マップ(辞書のようなもの)を処理する
説明 マップ(キーと値のペア)もrange
で簡単に処理できます。
例:色の名前と英語名の対応
package main
import "fmt"
func main() {
colors := map[string]string{
"赤": "red",
"青": "blue",
"緑": "green",
"黄": "yellow",
}
for japanese, english := range colors {
fmt.Printf("%s は英語で %s\n", japanese, english)
}
}
実行結果
赤 は英語で red
青 は英語で blue
緑 は英語で green
黄 は英語で yellow
文字列を1文字ずつ処理する
説明 文字列もrange
で1文字ずつ処理できます。
例
package main
import "fmt"
func main() {
text := "Hello"
for i, char := range text {
fmt.Printf("%d文字目: %c\n", i, char)
}
}
実行結果
0文字目: H
1文字目: e
2文字目: l
3文字目: l
4文字目: o
ループの制御:break と continue

break:ループを抜ける
説明 break
を使うと、ループを途中で終了できます。
例:特定の値が見つかったら止める
package main
import "fmt"
func main() {
numbers := []int{1, 3, 5, 8, 9, 12}
for i, num := range numbers {
if num%2 == 0 { // 偶数かチェック
fmt.Printf("%d番目に偶数 %d を発見!\n", i, num)
break
}
fmt.Printf("%d は奇数\n", num)
}
}
実行結果
1 は奇数
3 は奇数
5 は奇数
3番目に偶数 8 を発見!
continue:次の繰り返しにスキップ
説明 continue
を使うと、残りの処理をスキップして次の繰り返しに進めます。
例:偶数だけを表示する
package main
import "fmt"
func main() {
for i := 1; i <= 10; i++ {
if i%2 != 0 { // 奇数の場合
continue // スキップして次へ
}
fmt.Printf("%d は偶数\n", i)
}
}
実行結果
2 は偶数
4 は偶数
6 は偶数
8 は偶数
10 は偶数
実際に使える例
ファイルの内容を1行ずつ処理
例
package main
import (
"bufio"
"fmt"
"os"
"strings"
)
func main() {
// ファイルを開く(存在しない場合はエラー)
file, err := os.Open("sample.txt")
if err != nil {
fmt.Println("ファイルが開けません:", err)
return
}
defer file.Close()
scanner := bufio.NewScanner(file)
lineNumber := 1
for scanner.Scan() {
line := scanner.Text()
fmt.Printf("%d行目: %s\n", lineNumber, line)
lineNumber++
}
}
合計と平均を計算
例
package main
import "fmt"
func main() {
scores := []int{85, 92, 78, 96, 88, 75, 89}
total := 0
for _, score := range scores {
total += score
}
average := float64(total) / float64(len(scores))
fmt.Printf("点数: %v\n", scores)
fmt.Printf("合計: %d点\n", total)
fmt.Printf("平均: %.1f点\n", average)
}
実行結果
点数: [85 92 78 96 88 75 89]
合計: 603点
平均: 86.1点
最大値と最小値を見つける
例
package main
import "fmt"
func main() {
numbers := []int{45, 23, 67, 89, 12, 56, 78}
if len(numbers) == 0 {
fmt.Println("データがありません")
return
}
max := numbers[0]
min := numbers[0]
for _, num := range numbers {
if num > max {
max = num
}
if num < min {
min = num
}
}
fmt.Printf("データ: %v\n", numbers)
fmt.Printf("最大値: %d\n", max)
fmt.Printf("最小値: %d\n", min)
}
実行結果
データ: [45 23 67 89 12 56 78]
最大値: 89
最小値: 12
よくある間違いと注意点

無限ループにしてしまう
間違った例
i := 0
for i < 5 {
fmt.Println(i)
// i++ を忘れると永遠に続く!
}
正しい例
i := 0
for i < 5 {
fmt.Println(i)
i++ // 必ず更新を忘れずに
}
rangeの変数を別の関数で使う時の注意
問題のある例
package main
import (
"fmt"
"time"
)
func main() {
numbers := []int{1, 2, 3}
for _, num := range numbers {
go func() {
time.Sleep(100 * time.Millisecond)
fmt.Println(num) // 期待通りにならない
}()
}
time.Sleep(1 * time.Second)
}
正しい例
for _, num := range numbers {
num := num // 新しい変数として作り直す
go func() {
time.Sleep(100 * time.Millisecond)
fmt.Println(num) // 期待通りになる
}()
}
インデックスの範囲を間違える
注意点 スライスのインデックスは0から始まります。
例:正しいインデックスの使い方
fruits := []string{"りんご", "バナナ", "オレンジ"}
// 正しい:0, 1, 2
for i := 0; i < len(fruits); i++ {
fmt.Printf("%d: %s\n", i, fruits[i])
}
// 間違い:1から始めるとエラーになる可能性
for文の使い分けガイド
やりたいこと | 使う形 | 例 |
---|---|---|
決まった回数繰り返す | for i := 0; i < n; i++ | カウンター、繰り返し処理 |
条件が満たされるまで | for 条件 | ユーザー入力待ち |
永遠に続ける | for {} | サーバー、監視処理 |
スライスの処理 | for i, v := range slice | データの一覧処理 |
マップの処理 | for k, v := range map | 辞書データの処理 |
まとめ
Go言語のfor文の特徴
シンプルさ
- 1つのfor文ですべての繰り返し処理ができる
- 覚える構文が少ないので初心者にやさしい
柔軟性
- カウンター付きループ
- 条件付きループ(while文風)
- 無限ループ
- range を使った要素の繰り返し
実用性
- ファイル処理、データ集計、検索など実際の開発でよく使う
覚えておくべきパターン
// 基本的なカウンター
for i := 0; i < 10; i++ {
// 処理
}
// 条件だけ(while風)
for 条件 {
// 処理
}
// 無限ループ
for {
// 処理
if 終了条件 {
break
}
}
// スライスの処理
for i, value := range slice {
// 処理
}
// マップの処理
for key, value := range map {
// 処理
}
コメント