Goでforループを構築する方法

前書き

コンピュータプログラミングでは、_loop_は、多くの場合、何らかの条件が満たされるまでループを繰り返してコードの一部を実行するコード構造です。 コンピュータープログラミングでループを使用すると、同様のタスクを複数回自動化して繰り返すことができます。 処理する必要のあるファイルのリストがある場合、または記事の行数をカウントする場合を想像してください。 これらのタイプの問題を解決するには、コードでループを使用します。

Goでは、「+ for 」ループは、ループカウンターまたはループ変数に基づいてコードの繰り返し実行を実装します。 ` while `、 ` do `などの複数のループ構造を持つ他のプログラミング言語とは異なり、Goには ` for +`ループのみがあります。 これは、同じループ構造を実現するために複数の戦略を心配する必要がないため、コードをより明確で読みやすくするのに役立ちます。 開発時の読みやすさの向上と認知負荷の軽減により、他の言語よりもコードがエラーになりにくくなります。

このチュートリアルでは、Goの「+ for 」ループがどのように機能するかを、3つの主要なバリエーションを含めて学習します。 まず、さまざまなタイプの「 for +」ループを作成する方法を示し、次にhttps://www.digitalocean.com/community/tutorials/understanding-arrays-and-slices-in-go [ Goの順次データ型]。 最後に、ネストされたループの使用方法を説明します。

ForClauseおよび条件ループの宣言

さまざまなユースケースを説明するために、Goで「+ for 」ループを作成する3つの異なる方法があり、それぞれ独自の機能があります。 これらは、* Condition *、* ForClause *、または* RangeClause *で ` for +`ループを作成するためのものです。 このセクションでは、ForClauseおよびConditionバリアントを宣言して使用する方法を説明します。

最初にFor節で「+ for」ループを使用する方法を見てみましょう。

ForClauseループ_は、_initial statement、その後に_condition post post_の順に定義されます。 これらは、次の構文で配置されます。

for [  ] ; [  ] ; [  ] {
   []
}

上記のコンポーネントの機能を説明するために、From句構文を使用して、指定された値の範囲をインクリメントする「+ for」ループを見てみましょう。

for i := 0; i < 5; i++ {
   fmt.Println(i)
}

このループを分解して、各部分を識別しましょう。

ループの最初の部分は `+ i:= 0 +`です。 これは最初のステートメントです。

for ; i < 5; i++ {
   fmt.Println(i)
}

「+ i 」という変数を宣言し、初期値を「+0」に設定していることを示しています。

次は条件です。

for i := 0; ; i++ {
   fmt.Println(i)
}

この条件では、「+ i 」が「+5」の値よりも小さい間、ループはループを継続する必要があると述べました。

最後に、postステートメントがあります。

for i := 0; i < 5;  {
   fmt.Println(i)
}

postステートメントでは、 + i +++ increment演算子を使用して反復が発生するたびに、ループ変数 `+ i +`を1つずつ増やします。

このプログラムを実行すると、出力は次のようになります。

Output0
1
2
3
4

ループは5回実行されました。 最初に、「+ i 」を「+0」に設定し、「+ i 」が「+5」よりも小さいかどうかを確認しました。 `+ i `の値が ` 5 `より小さいため、ループが実行され、 ` fmt.Println(i)`のアクションが実行されました。 ループが終了した後、 ` i +`のpostステートメントが呼び出され、 `+ i +`の値が1増加しました。

0から開始するか、指定した値で終了することに限定されません。 最初のステートメントに任意の値を割り当てることができ、また、ポストステートメントの任意の値で停止できます。 これにより、必要な範囲を作成してループすることができます。

for i := 20; i < 25; i++ {
   fmt.Println(i)
}

ここで、反復は20(包括的)から25(包括的)に変わるため、出力は次のようになります。

Output20
21
22
23
24

postステートメントを使用して、異なる値で増分することもできます。 これは他の言語の `+ step +`に似ています:

最初に、正の値を持つpostステートメントを使用しましょう。

for i := 0; i < 15;  {
   fmt.Println(i)
}

この場合、0から15までの数字が出力されるように「+ for +」ループが設定されますが、3ずつ増加するため、次のように3つおきに数字が出力されます。

Output0
3
6
9
12

postステートメント引数に負の値を使用して逆方向に反復することもできますが、それに応じて初期ステートメント引数と条件引数を調整する必要があります。

for i := 100; i > 0; i -= 10 {
   fmt.Println(i)
}

ここでは、「+ i 」を「+100」の初期値に設定し、「+ i <0+」の条件を使用して「0」で停止し、postステートメントは値を10ずつ減少させます`-= +`演算子。 ループは「+100」で始まり、「+ 0+」で終わり、反復ごとに10ずつ減少します。 これは、出力で確認できます。

Output100
90
80
70
60
50
40
30
20
10

`+ for +`構文から初期ステートメントと事後ステートメントを除外し、条件のみを使用することもできます。 これは_Condition loop_と呼ばれるものです:

i := 0
for  {
   fmt.Println(i)
   i++
}

今回は、前のコード行で変数「+ in」を「+ for」ループとは別に宣言しました。 ループには、「+ i 」が「+5」より小さいかどうかを確認する条件句のみがあります。 条件が「+ true +」と評価される限り、ループは反復し続けます。

特定のタスクを完了するために必要な反復回数がわからない場合があります。 その場合、すべてのステートメントを省略し、 `+ break +`キーワードを使用して実行を終了できます。

for {



   // do action here
}

これの例は、https://golang.org/pkg/bytes/#Buffer [buffer]のような不定サイズの構造から読み込んでいて、いつ読み終えるかわからない場合です。

buffer.go

package main

import (
   "bytes"
   "fmt"
   "io"
)

func main() {
   buf := bytes.NewBufferString("one\ntwo\nthree\nfour\n")

   for {
       line, err := buf.ReadString('\n')
       if err != nil {
           if err == io.EOF {

               fmt.Print(line)
               break
           }
           fmt.Println(err)
           break
       }
       fmt.Print(line)
   }
}

上記のコードでは、 + buf:= bytes.NewBufferString(" one \ ntwo \ nthree \ nfour \ n ")+`はデータを含むバッファーを宣言します。 バッファの読み取りがいつ完了するかわからないため、句のない「+ for」ループを作成します。 `+ for +`ループ内で、 `+ line、err:= buf.ReadString( '\ n')+`を使用してバッファーから行を読み取り、バッファーからの読み取りエラーがあるかどうかを確認します。 あった場合は、エラーに対処し、https://www.digitalocean.com/community/tutorials/using-break-and-continue-statements-when-working-with-loops-in-go [+ forループを終了するbreak + `キーワード]。 これらの「+ break +」ポイントを使用すると、ループを停止するための条件を含める必要はありません。

このセクションでは、ForClauseループを宣言し、それを使用して既知の値の範囲を反復処理する方法を学びました。 また、特定の条件が満たされるまで条件ループを使用して繰り返す方法も学びました。 次に、RangeClauseを使用してシーケンシャルデータ型を反復処理する方法を学習します。

RangeClauseを使用したシーケンシャルデータ型のループ

Goでは、「+ for 」ループを使用して、https://www.digitalocean.com/community/tutorials/understanding-arrays-and-slices-in-go [スライス、配列]、https://www.digitalocean.com/community/tutorials/an-introduction-to-working-with-strings-in-go [strings]。 これを簡単にするために、_ RangeClause _構文で ` for`ループを使用できます。 ForClause構文を使用してシーケンシャルデータ型をループできますが、RangeClauseはより簡潔で読みやすいです。

RangeClauseを使用する前に、ForClause構文を使用してスライスを反復処理する方法を見てみましょう。

main.go

package main

import "fmt"

func main() {
   sharks := []string{"hammerhead", "great white", "dogfish", "frilled", "bullhead", "requiem"}




}

これを実行すると、次の出力が得られ、スライスの各要素が出力されます。

Outputhammerhead
great white
dogfish
frilled
bullhead
requiem

次に、RangeClauseを使用して同じアクションセットを実行しましょう。

main.go

package main

import "fmt"

func main() {
   sharks := []string{"hammerhead", "great white", "dogfish", "frilled", "bullhead", "requiem"}




}

この場合、リスト内の各アイテムを印刷しています。 変数「+ i 」と「 shark +」を使用しましたが、変数を他のhttps://www.digitalocean.com/community/tutorials/how-to-use-variables-and-constants-inと呼ぶこともできます。 -go#naming-variables-rules-and-style [有効な変数名]と同じ出力が得られます。

Output0 hammerhead
1 great white
2 dogfish
3 frilled
4 bullhead
5 requiem

スライスで `+ range `を使用すると、常に2つの値が返されます。 最初の値は、ループの現在の反復が含まれるインデックスになり、2番目の値はそのインデックスの値になります。 この場合、最初の反復では、インデックスは「+0」で、値は「+ hammerhead +」でした。

インデックスではなく、スライス要素内の値のみが必要な場合があります。 ただし、上記のコードを変更して値のみを出力すると、コンパイル時エラーが発生します。

main.go

package main

import "fmt"

func main() {
   sharks := []string{"hammerhead", "great white", "dogfish", "frilled", "bullhead", "requiem"}

   for i, shark := range sharks {

   }
}
Outputsrc/range-error.go:8:6: i declared and not used

`+ i `は ` for `ループで宣言されていますが、使用されていないため、コンパイラは ` iが宣言され使用されていない+`のエラーで応答します。 これは、変数を宣言して使用しないときにGoで受け取るエラーと同じです。

このため、Goにはアンダースコア( + _ +)であるhttps://golang.org/ref/spec#Blank_identifier [空白識別子]があります。 `+ for `ループでは、空の識別子を使用して、 ` range +`キーワードから返された値を無視できます。 この場合、返される最初の引数であるインデックスを無視します。

main.go

package main

import "fmt"

func main() {
   sharks := []string{"hammerhead", "great white", "dogfish", "frilled", "bullhead", "requiem"}

   , shark := range sharks {
       fmt.Println(shark)
   }
}
Outputhammerhead
great white
dogfish
frilled
bullhead
requiem

この出力は、「+ for」ループが文字列のスライスを反復処理し、インデックスなしでスライスから各アイテムを出力することを示しています。

`+ range +`を使用してリストに項目を追加することもできます:

main.go

package main

import "fmt"

func main() {
   sharks := []string{"hammerhead", "great white", "dogfish", "frilled", "bullhead", "requiem"}





   fmt.Printf("%q\n", sharks)
}
Output['hammerhead', 'great white', 'dogfish', 'frilled', 'bullhead', 'requiem', 'shark', 'shark', 'shark', 'shark', 'shark', 'shark']

ここでは、 `+ sharks `スライスの長さの各アイテムに `" shark "+`のプレースホルダー文字列を追加しました。

空の識別子 `+ _ `を使用して、 ` range `演算子からの戻り値を無視する必要がないことに注意してください。 Goでは、どちらの戻り値も使用する必要がない場合、 ` range +`ステートメントの宣言部分全体を省くことができます。

`+ range +`演算子を使用して、スライスの値を入力することもできます。

main.go

package main

import "fmt"

func main() {
   integers := make([]int, 10)
   fmt.Println(integers)





   fmt.Println(integers)
}

この例では、スライス「+ integer」は10個の空の値で初期化されますが、「+ for」ループはリスト内のすべての値を次のように設定します。

Output[0 0 0 0 0 0 0 0 0 0]
[0 1 2 3 4 5 6 7 8 9]

スライス `+ integers `の値を初めて印刷すると、すべてゼロが表示されます。 次に、各インデックスを反復処理し、値を現在のインデックスに設定します。 次に、2回目に「 integers 」の値を出力すると、すべての値が「+0」から「9」になっていることがわかります。

`+ range +`演算子を使用して、文字列内の各文字を反復処理することもできます。

main.go

package main

import "fmt"

func main() {
   sammy := "Sammy"

   for _, letter := range sammy {
       fmt.Printf("%c\n", letter)
   }
}
OutputS
a
m
m
y

mapを反復処理すると、「+ range +」は* key value *の両方を返します。

main.go

package main

import "fmt"

func main() {
   sammyShark := map[string]string{"name": "Sammy", "animal": "shark", "color": "blue", "location": "ocean"}

   for key, value := range sammyShark {
       fmt.Println(key + ": " + value)
   }
}
Outputcolor: blue
location: ocean
name: Sammy
animal: shark

「+ range」「+ for」ループを使用して順次データを反復処理する方法を学習したので、ループ内でループを使用する方法を見てみましょう。

ネストされたForループ

ループは、他のプログラミング言語と同様に、Goでネストできます。 _Nesting_は、ある構造が別の構造の中にある場合です。 この場合、ネストされたループは、別のループ内で発生するループです。 これらは、データセットのすべての要素でループアクションを実行する場合に役立ちます。

ネストされたループは、https://www.digitalocean.com/community/tutorials/how-to-write-conditional-statements-in-go#nested-if-statements [ネストされた `+ if +`ステートメント]と構造的に類似しています。 それらは次のように構築されます:

for {
   []
   for {
       []
   }
}

プログラムは最初に外側のループに遭遇し、最初の反復を実行します。 この最初の反復により、内部のネストされたループがトリガーされ、完了まで実行されます。 その後、プログラムは外側のループの先頭に戻り、2回目の反復を完了して、再びネストされたループをトリガーします。 繰り返しますが、ネストされたループは完了するまで実行され、プログラムはシーケンスが完了するか、ブレークまたはその他のステートメントによってプロセスが中断されるまで、外側のループの先頭に戻ります。

ネストされた「+ for」ループを実装して、詳しく見ていきましょう。 この例では、外側のループは「+ numList 」と呼ばれる整数のスライスを反復処理し、内側のループは「 alphaList +」と呼ばれる文字列のスライスを反復処理します。

main.go

package main

import "fmt"

func main() {
   numList := []int{1, 2, 3}
   alphaList := []string{"a", "b", "c"}

   for _, i := range numList {
       fmt.Println(i)
       for _, letter := range alphaList {
           fmt.Println(letter)
       }
   }
}

このプログラムを実行すると、次の出力が表示されます。

Output1
a
b
c
2
a
b
c
3
a
b
c

出力は、プログラムが「1」を印刷することにより外側のループの最初の反復を完了し、それが内側のループの完了をトリガーし、「+ a 」、「 b 」、「 c 」を連続して印刷することを示しています。 内側のループが完了すると、プログラムは外側のループの先頭に戻り、「 2+」を印刷してから、内側のループ全体を再度印刷します(「+ a 」、「 b 」、「 c +」)など

ネストされた「+ for」ループは、スライスで構成されるスライス内のアイテムを反復処理するのに役立ちます。 スライスで構成されるスライスでは、1つの「+ for +」ループのみを使用すると、プログラムは各内部リストをアイテムとして出力します。

main.go

package main

import "fmt"

func main() {
   ints := [][]int{
       []int{0, 1, 2},
       []int{-1, -2, -3},
       []int{9, 8, 7},
   }

   for _, i := range ints {
       fmt.Println(i)
   }
}
Output[0 1 2]
[-1 -2 -3]
[9 8 7]

内部スライスの個々のアイテムにアクセスするために、ネストされた「+ for +」ループを実装します。

main.go

package main

import "fmt"

func main() {
   ints := [][]int{
       []int{0, 1, 2},
       []int{-1, -2, -3},
       []int{9, 8, 7},
   }

   for _, i := range ints {
       for _, j := range i {
           fmt.Println(j)
       }
   }
}
Output0
1
2
-1
-2
-3
9
8
7

ここでネストされた「+ for」ループを使用すると、スライスに含まれる個々のアイテムを反復処理できます。

結論

このチュートリアルでは、Goで反復タスクを解決するために、 `+ for `ループを宣言して使用する方法を学びました。 また、「 for 」ループの3つの異なるバリエーションと、それらを使用するタイミングについても学びました。 「 for +」ループとそれらのフローを制御する方法の詳細については、https://www.digitalocean.com/community/tutorials/using-break-and-continue-statements-when-working-with-loopsをお読みください-in-go [Goでループを操作するときにBreakステートメントとContinueステートメントを使用する]。