【Go言語入門】for文の使い方まとめ!基本から応用までやさしく解説

Go

プログラミングでは、同じ処理を何度も繰り返すことがよくあります。

多くのプログラミング言語では、forwhiledo 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 {
    // 処理
}

コメント

タイトルとURLをコピーしました