이 글은 Effective Go를 일부 번역한 글입니다.


제어 구조

Go의 제어 구조는 C의 그것과 연관이 있지만 중요한 차이가 있다. dowhile 반복이 없고 조금 일반화된 for만 있다. switch는 더 유연하다. ifswitch에도 for처럼 초기화 문장을 넣을 수 있다. breakcontinue 문장엔 이름표를 붙여 벗어나거나 재개할 것을 지정할 수 있다. 또한 새롭게 type switch와 다방향 통신 멀티플렉서 select가 제어 구조에 추가되었다. 구문도 약간 다르다. 괄호가 없으며 본문은 반드시 항상 중괄호로 감싸야 한다.

재선언과 재할당

여담으로, 이전 절의 마지막 예제는 := 축약 선언 형태가 어떻게 작동하는지 자세히 보여준다. os.Open을 호출하는 선언은 이렇다.

f, err := os.Open(name)

이 문장은 ferr 두 변수를 선언한다. 몇 줄 내려가 보면 f.Stat 호출은 이렇다.

d, err := f.Stat()

이는 derr를 선언하는 것처럼 보인다. 하지만 잘 보라. 두 문장 모두 err를 이야기한다. 이 중복은 정당하다. 첫 문장에 err를 선언했지만, 두 번째 문장은 err에 재할당했을 뿐이다. 즉, f.Stat 호출은 이미 위에 선언되어 존재하는 err 변수를 사용하며, 새 값을 할당했을 뿐이다.

:= 선언에서 이미 선언된 변수 v를 사용할 수 있는 조건은 아래와 같다.

  • 해당 선언이 이미 존재하는 v의 선언과 같은 유효 범위에 있고, (v를 상위 유효 범위에서 선언했으면 해당 선언은 새로운 변수를 생성한다. §)
  • 초기화에서 v에 해당하는 값이 v에 할당할 수 있는 값이어야 하며,
  • 선언에 새로 선언하는 다른 변수가 적어도 하나는 있어야 한다.

이 보기 드문 특성은 굉장히 실용적이다. 이를테면 if-else가 길게 늘어져 있을 때 err 값 하나만 사용하기 편하게 해준다. 이렇게 자주 쓰는 걸 보게 될 것이다.

§ 기억해두는 게 좋다. Go에선 함수 본문을 감싸는 중괄호 밖에 함수 매개 변수와 반환 값을 두지만, 그 유효 범위는 함수 본문과 같다.