Goto 문

Goto 문

"goto" 문은 같은 함수 안에서 대응하는 label이 붙은 문으로 제어 흐름을 옮겨요. 저장공간이 아닌 실행 위치를 가리키는 점프인데, 여기에도 Go만의 엄격한 규칙 두 가지가 따라와요 — 하나는 변수의 생성(scope)을 건너뛰면 안 된다는 것, 다른 하나는 블록 바깥에서 블록 안으로는 점프할 수 없다는 거예요. 코드로 하나씩 확인해 볼게요.

출처: Go Specification

본문

"goto" 문은 같은 함수 안에서 대응하는 label이 붙은 문으로 제어 흐름을 옮겨요.

GotoStmt = "goto" [Label](https://go.dev/ref/spec#Label) .

예를 들어 이런 식이에요.

goto Error

"goto" 문을 실행할 때, 그 goto 지점에서 이미 scope 안에 있지 않던 변수를 새로 scope 안으로 들여오게 만들어서는 안 돼요. 예를 들어 다음 코드는 잘못됐어요.

	goto L  // BAD
	v := 3
L:

label L로 점프하면 변수 v의 생성(creation)을 건너뛰기 때문이에요. 즉 goto L이 실행되는 순간 v는 아직 만들어지지 않았는데, L: 뒤로 제어가 넘어간 뒤에도 v가 존재한다는 전제가 깨져요.

또 하나, 블록 바깥에 있는 "goto" 문은 그 블록 안에 있는 label로 점프할 수 없어요. 예를 들어 다음 코드는 잘못됐어요.

if n%2 == 1 {
	goto L1
}
for n > 0 {
	f()
	n--
L1:
	f()
	n--
}

label L1이 "for" 문의 블록 안에 있는데 goto는 그 블록 밖에 있기 때문이에요. 블록 안에서 밖으로는 자유롭게 나갈 수 있어도, 밖에서 안으로는 들어갈 수 없다고 기억하면 편해요.

더 알아보기

  • Label 선언과 scope 규칙 — goto가 가리키는 label이 어디까지 유효한지의 기준이 돼요.
  • 선언과 scope — goto가 변수의 scope를 건너뛰면 안 되는 이유가 여기서 나와요.
  • 블록 — 블록 경계를 넘는 제어 이동 제약의 배경이 돼요.