Go에서 포어 루프를 생성하는 방법

소개

컴퓨터 程式的에서, 루프는 일정 기능을 繰가하는 코드 구조를 의미합니다. 루프를 사용하여 일반적인 일을 자동화하고 여러 번 실행할 수 있습니다. 比如说, 일련의 파일을 처리하거나 記事의 行의 개수를 카운트하는 것과 같은 일을 하는 것입니다. 이러한 일을 해결하기 위해 코드에 루프를 사용합니다.

Go에서는 for 루프를 사용하여 카운터나 루프 변수를 기반으로 코드를 반복적으로 실행합니다. 다른 程式的어떤 언어들이 while, do 등의 다양한 루프 구조를 갖추고 있지만, Go에서는 이를 제외하고 for 루pe가 unique로 存在하게 됩니다. 이렇게 코드를 더욱 명확하고 읽기 쉽게 만들며, 동일한 루pe 구조를 달성하기 위해 다양한 전략을 고민할 필요가 없습니다. 이러한 코드의 읽기 어려움과 개발 시간 내에 인지 부하를 줄이면서, 다른 언어들에 비해 에러가 발생하는 것을 예방합니다.

이 튜토리얼에서는 Go의 for 루pe가 어떻게 작동하는지, 그리고 그것의 세 가지 주요 용法的 변형을 배울 것입니다. 우선 다양한 형태의 for 루pe를 생성하는 방법을 보여줍니다. 그 다음, Go에서 순차 자료형을 사용하는 방법을 배울 것입니다. 마지막으로 깊은 嵌套 루pe의 사용方法을 설명할 것입니다.

ForClause와 Condition 루프 선언

다양한 사용 사례를考慮하기 위해 Go에서 for 루프를 생성하는 세 가지 서로 다른 방법이 있으며, 각각은 고유한 기능을 가지고 있습니다. 이는 Condition, ForClause, 또는 RangeClause를 사용하여 for 루프를 만드는 방법입니다. 이 섹션에서는 ForClause와 Condition 변형을 어떻게 선언하고 사용하는지 설명합니다.

먼저 ForClause를 사용한 for 루프를 어떻게 사용할 수 있는지 살펴보겠습니다.

ForClause 루프초기 문장 뒤에 조건을 따라 후속 문장으로 구성됩니다. 이는 다음 문법으로 배열됩니다:

for [ Initial Statement ] ; [ Condition ] ; [ Post Statement ] {
    [Action]
}

이전 구성 요소들이 무엇을 하는지 설명하기 위해, ForClause 문법을 사용하여 지정된 범위의 값을 증가시키는 for 루프를 살펴보겠습니다:

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

이 루프를 분해하고 각 부분을 식별해 봅시다.

루프의 첫 부분은 i := 0입니다. 이것은 초기 문장입니다:

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

이 문장은 i라는 변수를 선언하고, 초기 값을 0으로 설정한다는 것을 의미합니다.

다음은 조건입니다:

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

이 조건에서는 i5보다 작은 동안 루프가 계속 반복되어야 한다고 지정했습니다.

마지막으로 후속 문장입니다:

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

在声明中,每次迭代时我们使用 `i++` 递增 运算符将循环变量 i 增加一。

当我们运行此程序时,输出如下所示:

Output
0 1 2 3 4

循环运行了5次。最初,它将 i 设置为 0,然后检查 i 是否小于 5。由于 i 的值小于 5,因此循环执行,并执行了 fmt.Println(i) 动作。循环结束后,调用了 i++ 的后置声明,i 的值增加了1。

注意: 请记住,在编程中我们倾向于从索引0开始,这就是为什么虽然输出了5个数字,但它们的范围是0-4。

我们不仅限于从0开始或以指定的值结束。我们可以为我们的初始声明分配任何值,并且在后置声明中以任何值停止。这允许我们创建任何所需的范围来循环遍历:

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

在这里,迭代从20(包含)到25(不包含),所以输出如下所示:

Output
20 21 22 23 24

我们还可以使用后置声明以不同的值递增。这与其他语言中的 `step` 类似:

首先,使用带有正值的后置声明:

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

在这种情况下,`for` 循环设置为从0到15打印数字,但以3为增量,因此只打印每第三个数字,如下所示:

Output
0 3 6 9 12

我们也可以使用负值作为我们的post语句参数来回退迭代,但是我们需要相应地调整我们的初始语句和条件参数:

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

在这里,我们将i设置为初始值为100,使用条件i < 00处停止,并通过-=操作符将值减少10。循环从100开始,以每次迭代减少10的方式结束于0。我们可以在输出中看到这一点:

Output
100 90 80 70 60 50 40 30 20 10

您还可以将初始语句和post语句从for语法中排除,只使用条件。这被称为条件循环

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

这次,我们在for循环前面的代码行中单独声明了变量i。循环仅有一个条件子句,用于检查i是否小于5。只要条件评估为true,循环将继续进行迭代。

有时,您可能不知道需要执行多少次迭代才能完成某些任务。在这种情况下,您可以省略所有语句,并使用break关键字退出执行:

for {
	if someCondition {
break
}
	// 在此执行操作
}

一个这样的例子可能是,如果我们正在读取一个不确定的结构,如缓冲区,并且我们不知道何时读完:

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”)`는 一些의 데이터가 있는 버퍼를 선언합니다. 버퍼가 何时 읽기를 완료할지 모르므로, CLAUSE가 없는 `for` 루프를 생성합니다. `for` 루프 내에서, `line, err := buf.ReadString(‘\n’)` 을(를) 사용하여 버퍼から 一行을 읽고, 버퍼から 읽기 시간 문제가 있는지 여부를 확인합니다. 문제가 있으면, 에러를 처리하고, `for` 루프를 退出하기 위해 `break` 关键字을 사용합니다.. 이러한 `break` 지점을 통해, 루프를 중지하는 조건을 포함할 필요가 없습니다.

이 섹션에서, ForClause 루프를 선언하고 어떻게 이를 사용하여 알고 있는 범위의 값을 이룰方法을 배웠습니다. 또한, 어떻게 Condition 루프를 사용하여 특정 조건을 만족시키기 전까지 반복하는 方法을 배웠습니다. 次に, RangeClause가 어떻게 連贯적인 자료형을 이룰 方法을 배울 것입니다.

RangeClause로 連贯적인 자료형을 이룰 方法

Go에서는 순차 또는 컬렉션 자료 유형, 如火伴 slice, 배열, 以及 字符串 등에 대해 for 루프를 사용하여 요소를 이룰 것이 일반적입니다. 이러한 과정에서 for 루프를 RangeClause 문법과 함께 사용할 수 있으며, 이를 통해 순차 자료 유형에 대해 ForClause 문법을 사용하여 루프를 돌 수 있지만, RangeClause는 더 맘에 들고 읽기 좋습니다.

RangeClause를 사용하기 전에, ForClause 문법을 사용하여 슬라이스를 이룰 수 있는 방법을 살펴봅니다:

main.go
package main

import "fmt"

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

	for i := 0; i < len(sharks); i++ {
		fmt.Println(sharks[i])
	}
}

이 명령을 실행하면 다음과 같은 출력이 나며, 슬라이스의 각 요소를 찍습니다:

Output
hammerhead great white dogfish frilled bullhead requiem

이제 RangeClause를 사용하여 같은 행동을 수행하도록 하겠습니다:

main.go
package main

import "fmt"

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

	for i, shark := range sharks {
		fmt.Println(i, shark)
	}
}

이 경우에는 리스트의 각 아이템을 찍고 있습니다. 여기에서는 ishark라는 変수를 사용했지만, 다른 任何 有効な変数명을 사용하여 같은 출력이 나올 것입니다:

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

슬라이스에 대해 range를 사용할 때, 항상 두 값을 반환합니다. 첫 번째 값은 루프의 현재 iteration이 있는 인덱스입니다, 그리고 두 번째 값은 그 인덱스에 있는 값입니다. 이 경우, 첫 번째 iteration에서는 인덱스가 0이었고, 값은 hammerhead였습니다.

때때로, 슬라이스 요소 안의 값만 얻고 인덱스를 사용하지 않고 싶을 때가 있습니다. 그러나 이전 코드를 값만 표시하는 것으로 변경하면 컴파일 시간 에러가 발생합니다.

main.go
package main

import "fmt"

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

	for i, shark := range sharks {
		fmt.Println(shark)
	}
}
Output
src/range-error.go:8:6: i declared and not used

이러한 에러는 ifor 루프에서 선언되었지만 사용되지 않은 것으로 컴파일러가 i declared and not used 에러로 응답할 것입니다.

이러한 에러는 구(Go)에서도 변수를 선언하고 사용하지 않는다면 받을 수 있는 같은 에러입니다. 따라서, 구(Go)에는

main.go
package main

import "fmt"

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

	for _, shark := range sharks {
		fmt.Println(shark)
	}
}
Output
hammerhead great white dogfish frilled bullhead requiem

��(blank identifier)이라는 것이 있습니다. ��은 하이픈(_)로 구성되며, for 루프에서 range 키워드로 리턴되는 모든 값을 무시하기 위해 사용할 수 있습니다. 이 경우, 리턴된 첫 인자로 인덱스를 무시하고자 합니다.

이 출력은 for 루프가 문자열 슬라이스를 돌면서, 슬라이스의 인덱스를 打印하지 않고 각 아이템을 打印하는 것을 보여줍니다.

main.go
package main

import "fmt"

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

	for range sharks {
		sharks = append(sharks, "shark")
	}

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

여기에서는 sharks 슬라이스의 길이 만큼 기 placeholder 문자열 "shark"를 추가했습니다.

여기서는 _ ��이라는 空白 식별자를 사용하지 않고 리턴 값을 무시할 수 있었습니다. 구(Go)는 range 연산자의 hole declaration 부분을 사용하지 않는다면 리턴 값을 사용하지 않는다면 hole declaration 부분을 省略할 수 있다고 합니다.

또한, range 연산자를 사용하여 슬라이스의 값을 채우는 것도 가능합니다.

main.go
package main

import "fmt"

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

	for i := range integers {
		integers[i] = i
	}

	fmt.Println(integers)
}

이 예제에서, 슬라이스 integers는 十個의 빈 값으로 초기화되었지만, for 루프는 리스트에 모든 값을 다음과 같이 설정한다.

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

슬라이스 integers의 값을 처음으로 打印할 때, 모두 零이 보인다. 그 다음 각 인덱스를 이전 인덱스로 설정한다. 그러면 다시 integers의 값을 打印할 때, 모두 0에서 9까지의 값을 가지고 있음을 보여준다.

또한, range 연산자를 사용하여 문자열 中的 각 문자를 이터레이트할 수 있다.

main.go
package main

import "fmt"

func main() {
	sammy := "Sammy"

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

map을 이터레이트할 때, rangekeyvalue both를 리턴한다.

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)
	}
}
Output
color: blue location: ocean name: Sammy animal: shark

Note: 중요한 것은, Map가 리턴하는 顺序이 Arbitrary가 되는 것입니다. 이 프로그램을 실행하는 것마다 다른 결과를 얻을 수 있습니다.

이제 range for 루프를 이용해 顺序 데이터를 이터레이트하는 방법을 배웠으며, 다시 하나의 루프 안에 다른 루프를 사용하는 방법을 보자.

嵌套 For 루프

在其他编程语言中一样,Go 语言中也支持嵌套循环。嵌套 是指在一个结构内部包含另一个结构。在这种情况下,嵌套循环是指在一个循环内部发生的循环。当您希望对数据集中的每个元素执行循环操作时,嵌套循环非常有用。

嵌套循环在结构上与 嵌套的 if 语句 相似。它们的构造如下所示:

for {
    [Action]
    for {
        [Action]  
    }
}

程序首先遇到外层循环,执行其第一次迭代。这次迭代触发内嵌的、嵌套循环,然后运行到完成。然后程序返回外层循环的顶部,完成第二次迭代,并再次触发嵌套循环。像这样,嵌套循环运行到完成,程序返回外层循环的顶部,直到序列完成,或者 break 或其他语句打断这个过程。

让我们实现一个嵌套的 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)
		}
	}
}

当我们运行这个程序时,我们将得到以下输出:

Output
1 a b c 2 a b c 3 a b c

1이 印字되고, 이를 통해 a, b, c를 順番대로 印字한 내용이 나타남. 내부 루프가 완료되면, 프로그램은 外援로opl의 상단으로 돌아가 2를 印字하고, 다시 내부 루프를 完全하게 印字한다(a, b, c). 이러한 과정이 반복되는 것을 보여줌

外援로opl을 사용하여 슬라이스로 구성된 슬라이스의 내용을 반복하는 것이 유용하다. 슬라이스가 슬라이스로 구성되어 있을 때, 单独pl로opl을 사용하면 각 내부 목록을 独立的 아이템으로 출력한다.

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]

내부 슬라이스의 각 개별 아이템을 접근하기 위해 嵌套pl로opl을 사용한다.

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)
		}
	}
}
Output
0 1 2 -1 -2 -3 9 8 7

이곳에서 嵌套pl로opl을 사용하면 슬라이스 내에 포함된 개별 아이템을 반복할 수 있다.

결론

이 튜토리얼에서는 Go에서 반복적인 작업을 해결하기 위해 for 로opl을 선언하고 사용하는 방법을 배웠고, 세 가지 다른 유형의 for 로opl을 배웠고, 그들을 사용하는 적절한 상황을 배웠다. for 로opl의 자세한 정보와 어떻게 그들의 흐름을 제어하는지 배우고자 하시면 Go로opl에서 인자를 사용하는 방법을 읽으시기 바랍니다.

Source:
https://www.digitalocean.com/community/tutorials/how-to-construct-for-loops-in-go