여러가지 형태의 for 사용법 및 레이블로 빠져나가기
on Go
Go 에는 while 루프가 없기 때문에, 사실상 for 를 사용해 while 처럼 동작하게 해야 한다.
for문에 들어갈 초기문, 조건문, 후처리문에 대해 생략 가능하게 만들어져있기 때문에 다양한 방식으로 활용이 가능하다.
아래는 가장 기본적인 for문의 형태이다.
for 초기문 ; 조건문 ; 후처리문 {
// statements
}
아래처럼 반복에 들어가기 전에 한번 실행하는 초기문을 생략할 수 있으며, 생략한다고 하더라도 문장들을 구분해주는 ;
를 빼먹는것은 안된다.
for ; 조건문 ; 후처리문 {
// statements
}
초기문 뿐만 아니라 후처리 하는 문장도 생략 가능하다.
for 초기문 ; 조건문 ; {
// statements
}
사실상 ; 조건문 ;
만 들어가 있을 경우 앞뒤에 뭐가 들어오든 상관 없다고 볼 수 있으며, 실제로 아래처럼 쓸 수도 있으며 while 문과 비슷한 형태가 된다.
for ; 조건문 ; {
//statements
}
조건문만 넣는 경우에는 ;
를 모두 없애고 사용할 수도 있다.
for 조건문 {
//statements
}
조건문을 생략할 경우에는 while True 처럼 무한루프가 된다.
for {
//statements
}
일반적으로 하나의 for 문을 빠져나가기 위해서는 break 을 사용한다.
그러나 중첩 for문을 한번에 빠져나가는 것은 지원되지 않기 때문에, 간단하게 플래그로써 사용할 bool 변수 하나를 두고 해당 플래그를 검사해 반복적으로 break 해나가는 방법을 사용하기도 한다.
파이썬 같은 경우에는 for-else 문 같은 것이 존재하기도 하는데, Go 에서는 특정 for 문에 해당하는 레이블을 지정하고 해당 레이블까지 break 이 가능하다.
for문을 시작하기 전에 해당 반복문의 레이블을 지정해 두고, break [레이블명]
과 같이 사용할 경우, 해당 for 문까지 빠져나오게 된다.
레이블은 for문 위에다가 레이블명에 콜론을 붙여 정의하며, 예를 들어 아래의 경우 이중포문을 돌리다가 i = j = 1 인 상황에서 break ForBreak
을 통해 i 와 관련된 for문 까지 같이 종료시킨다.
func main() {
ForBreak:
for i := 0 ; i < 3 ; i++ {
for j := 0 ; j < 3 ; j++ {
if i == 1 && j == 1 {
break ForBreak
}
fmt.Println(i, j)
}
}
}
0 0
0 1
0 2
1 0
레이블을 여러개 둠으로써 더 많은 중첩 속에서 필요에 맞게 break 할 수 있다.
func main() {
cnt := 0
Pbreak:
for p := 0 ; p < 3 ; p++ {
for q := 0 ; q < 3 ; q++ {
if cnt == 10 {
break Pbreak
}
Rbreak:
for r := 0 ; r < 3 ; r++ {
for c := 0 ; c < 3 ; c++ {
if r == 0 && c == 2 {
break Rbreak
}
cnt++
}
}
}
}
}
레이블은 버그를 발생시키는 원인이 되기도 하므로 권장하는 방법도 아니지만, 단순 로직을 짤 때 편리하긴 하다.
그래서 권장되는 방법으로는 반복문을 중첩시키다가 break 로 빠져나가는 것이 아닌, 잘라낼 수 있는 부분에 대해서는 따로 함수로 정의하여 그 안에서 return 하는 방식이 깔끔하다.