PR

Go言語(Golang)のループ処理の使い分け方まとめ

基礎

こんにちは。Tomoyuki(@tomoyuki65)です。

Go言語(Golang)によるループ処理については主に4つの方法がありますが、この記事ではそれらのループ処理の使い分け方についてまとめておきます。

 

Go言語(Golang)のループ処理の使い分け方まとめ

Go言語(Golang)によるループ処理の使い分け早見表は以下の通りです。

構文 種類 主な用途
for i:=0; i < n; i++ 基本的なforループ 回数が決まっている繰り返し処理
for condition 条件式のみのforループ(while) 特定の条件を満たすまでの繰り返し処理
for {} 無限ループ サーバーの待受など、意図的に止めない限り続く処理
for … range for-rangeループ スライス、マップなどの中身を順番に取り出す処理

 

基本的なforループ

・書き方

for 初期化; 条件式; 後処理 {
  // 処理
}

 

・こういう時に使う

「n回繰り返す」というように、実行回数が事前に明確な場合に最適です。

・特定の処理を5回だけ実行したい。
・配列やスライスの最初のn個だけ処理したい。

 

・コード例

// 0から4まで、5回繰り返す
for i := 0; i < 5; i++ {
  fmt.Printf("現在のカウント:%d\n", i)
}

// スライスの要素を逆順に出力する
items := []string{"a", "b", "c"}
for i := len(items) - 1; i >= 0; i-- {
  fmt.Println(items[i])
}

 

条件式のみのforループ(while)

・書き方

for 条件式 {
  // 処理
}

 

・こういう時に使う

繰り返し回数は決まっていないが、「この条件が満たされている間は処理を続けたい」という場合に使います。

・ファイルの終端に達するまで読み込みを続ける。
・特定のステータスがtrueになるまで待つ。
・エラーがなくなるまでリトライする。

 

・コード例

// sumが100未満の間、処理を続ける
sum := 1
for sum < 100 {
  sum += 1
}
fmt.Println(sum)

 

無限ループ

・書き方

for {
  // 処理
}

 

・こういう時に使う

プログラムが能動的に終了させない限り、常に動き続けてほしい処理に使います。

・チャネルからデータを受信し続ける処理(Goでは非常に一般的)。
・Webサーバーがリクエストを待ち受ける処理。
・バックグラウンドで定期的に何かを監視するデーモン的な処理。

 

・コード例

// チャネル
messageChan := make(chan string)

// チャネルにメッセージを送信するgoroutine
go func() {
  // メッセージ設定
  messages := []string{"こんにちは", "Go!", "goroutineテスト"}

  // メッセージ送信
  for _, msg := range messages {
    messageChan <- msg
  }

  // チャネルを閉じる
  close(messageChan)
}()

// 受信処理
for {
  msg, ok := <-messageChan
  if !ok {
    // チャネルが閉じられたらループを抜ける
    break
  }
  fmt.Println("受信:", msg)
}

※そのほかselect文と組み合わせて、複数のイベントを待ち受ける際にも多用されます。

 

for-rangeループ

・書き方

// スライスや配列の場合
for index, value := range collection {
  // 処理
}

// マップの場合
for key, value := range aMap {
  // 処理
}

 

・こういう時に使う

コレクション(スライス、マップなど)の全要素に対して、順番に何らかの処理を行いたい場合は、ほぼ常にこれを使います。

インデックスの管理を自分で行う必要がなく、コードが非常にシンプルになります。

・スライスの全要素を合計する。
・マップのキーと値を全て表示する。

 

・コード例

// スライスの例
total := 0
nums := []int{10, 20, 30}
for _, num := range nums {
  total += num
}
fmt.Println("合計:", total)


// マップの例
userAges := map[string]int{
  "Alice": 25,
  "Bob": 30,
}
for name, age := range userAges {
  fmt.Printf("%sは%d歳です。\n", name, age)
}

 

ループ処理の制御について

ループ処理については、breakとcontinueを使って挙動を制御できます。

・break:ループを即座に中断し、ループの外の次の処理に進みます。
・continue:現在の繰り返しを中断し、次のループ処理に進みます。

 

・コード例

for i := 0; i < 10; i++ {
  // 終了条件
  if i == 5 {
    fmt.Println("5になったのでループを抜けます。")
    break
  }

  // iが偶数の場合はスキップ
  if i%2 == 0 {
    continue
  }

  fmt.Printf("奇数:%d\n", i)
}

 

最適なループ処理の選び方

1. コレクション(スライス、マップなど)から値を取り出しながら処理させたい

→ for-rangeループを使う。最もGoらしい書き方。

 

2. 「5回」のように回数が決まっている

→ 基本的なforループを使う。

 

3. 回数はわからないが、特定の条件(n < 100など)を満たす間だけ続けたい

→ 条件式のみのforループ(while)を使う。

 

4. サーバーのようにずっと動き続けて欲しい

→ 無限ループを使い、必要に応じてbreakやreturnで抜ける。

※returnは関数の実行を終了して呼び出し元へ戻る

 

スポンサーリンク

最後に

今回はループ処理の使い分け方についてまとめました。

主に4種類あって使い慣れてないとどれを使えばいいか迷うこともあると思うので、そういった場合はぜひこの記事を参考にしてみて下さい。

 

この記事を書いた人
Tomoyuki

SE→ブロガーを経て、現在はWeb系エンジニアをしています!

Tomoyukiをフォローする
基礎
スポンサーリンク
Tomoyukiをフォローする

コメント

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