Menu

Golang while문: Go에서 while과 do-while 작성하는 법

Go에는 while 키워드가 없습니다. 조건만 있는 for 반복문이 Go의 while문이고, 조건이 없는 for는 무한 루프이며, do-while은 끝에서 조건을 검사하는 무한 루프입니다.

이 페이지에는 실행 가능한 에디터가 있습니다 - 편집하고 실행하면 결과를 바로 볼 수 있습니다.

Go에는 while 키워드가 없습니다. for 뒤에 조건을 쓰면 그게 while 반복문입니다:

조건은 매 반복 전에 검사되므로, 처음부터 거짓이면 본문은 한 번도 실행되지 않습니다. C, Java, JavaScript의 while (balance < 2000)과 같고, 괄호와 키워드만 빠졌습니다. Go 설계자들은 모든 반복 형태에 키워드 하나만 쓰기로 했습니다. 네 가지 형태는 for 반복문 페이지에서 볼 수 있습니다.

while(true): 무한 루프

조건을 아예 빼면, 안에서 무언가가 끝낼 때까지 반복이 계속됩니다:

관용적인 표기는 for { }입니다. for true { }도 컴파일되지만 다른 언어에서 온 사람이 쓴 코드처럼 읽힙니다.

무한 루프를 끝내는 방법은 네 가지입니다. break(반복문을 빠져나감), return(함수를 빠져나감), 패닉, 그리고 os.Exit입니다. main이 이 중 아무것도 없는 for {}에 머무는 프로그램은 강제로 종료될 때까지 실행되며, 서버나 워커라면 바로 그렇게 동작해야 합니다.

do-while

do-while은 조건을 검사하기 전에 본문을 한 번 실행합니다. Go에는 전용 문법이 없습니다. 무한 루프의 끝에 검사를 두면 됩니다:

본문은 무슨 일이 있어도 최소 한 번은 실행되고, 이것이 do-while을 정의하는 성질입니다. 이 예제의 난수 소스는 고정된 시드를 써서 실행할 때마다 같은 결과가 나옵니다. 진짜 무작위 값이 필요하면 시드를 지정한 소스 없이 rand.IntN을 쓰세요.

첫 번째 반복을 강제로 통과시켜 조건을 헤더에 남기는 두 번째 형태도 있습니다:

for first := true; first || condition(); first = false {
	// body
}

동작은 하지만, 끝에 break가 있는 무한 루프가 더 읽기 쉽고 대부분의 Go 코드도 그렇게 씁니다.

끝날 때까지 읽기

실제 Go 코드에서 가장 흔한 while 반복문은 입력이 떨어질 때까지 읽는 것입니다. bufio.Scanner가 바로 이 용도로 만들어졌습니다. Scan은 입력이 끝나거나 오류가 나면 false를 반환하므로 그대로 반복 조건이 됩니다:

strings.NewReader(input)os.Stdin으로 바꾸면 같은 반복문이 사용자 입력을 한 줄씩 읽습니다. 반복이 끝난 뒤 scanner.Err()를 확인하세요. Scanfalse를 반환했다는 것만으로는 입력이 정상적으로 끝났는지 실패했는지 알 수 없습니다.

break와 continue

둘 다 모든 형태의 for에서 동작합니다:

조건만 있는 반복문에서 continue는 곧바로 조건으로 건너뜁니다. 그래서 미묘한 버그가 생기기 쉽습니다. 카운터를 본문 맨 아래에서 갱신하면, 그보다 위에 있는 continue가 갱신을 건너뛰어 반복이 끝나지 않습니다. 위 예제처럼 카운터를 맨 위에서 갱신하거나, continue 뒤에도 후처리 문장이 실행되는 세 절짜리 for를 쓰세요.

무언가를 기다리기

조건을 기다리는 반복문은 헛돌지 말고 블록되거나 잠들어야 합니다:

// Wrong: burns a CPU core while waiting
for !ready {
}

// Better: poll with a delay
for !isReady() {
	time.Sleep(100 * time.Millisecond)
}

다른 고루틴이 쓰는 일반 변수를 폴링하는 것은 데이터 레이스이기도 합니다. 고루틴 사이에서는 채널, sync.WaitGroup, sync.Cond로 기다리거나 타이머와 함께 select를 쓰세요. 횟수 제한이 있는 재시도 반복문은 영원히 돌 수 없도록 횟수를 세는 for가 낫습니다:

for attempt := 1; attempt <= 5; attempt++ {
	if err := connect(); err == nil {
		break
	}
	time.Sleep(time.Duration(attempt) * 200 * time.Millisecond)
}

흔한 실수

  • 조건 변수를 바꾸는 것을 잊음. for i < 10 { fmt.Println(i) }는 끝나지 않습니다. 모든 while 반복문에는 본문 안에 종료 쪽으로 움직이게 하는 무언가가 있어야 합니다.
  • while을 씀. while x < 5 {}syntax error: unexpected name x at end of statement를 냅니다. while은 키워드가 아니라서 컴파일러가 평범한 이름으로 읽기 때문입니다.
  • 습관적인 괄호. for (x < 5) {}는 컴파일되고, gofmt가 괄호를 지웁니다.
  • 반복문 안에서 변수 선언. for n := 10; n > 0 {}는 문법 오류입니다. 초기화 절이 있는 반복문은 세 절이 모두 필요합니다. n을 반복문 앞에서 선언하거나 세 절 형태를 온전히 쓰세요.

자주 묻는 질문

Go에 while 반복문이 있나요?

키워드로는 없습니다. Go는 모든 반복문에 for를 쓰고, 조건만 있는 for가 정확히 while 반복문입니다:

for count < 10 {
	count++
}

조건은 매 반복 전에 검사되며, C나 Java의 while (count < 10)과 똑같습니다.

Go에서 while(true)는 어떻게 작성하나요?

뒤에 아무것도 없는 for를 씁니다: for { ... }. break, return, 패닉, os.Exit 중 하나가 끝낼 때까지 반복합니다. for true { ... }도 컴파일되지만 관용적인 형태는 for { }입니다.

Go에서 do-while 반복문은 어떻게 작성하나요?

무한 루프를 쓰고 조건 검사를 본문 끝에 둡니다:

for {
	// body runs at least once
	if !condition {
		break
	}
}

조건을 검사하기 전에 본문이 항상 한 번은 실행되며, 이것이 do-while의 의미입니다.

Coddy programming languages illustration

Coddy로 코딩 배우기

시작하기