Return 문(return statements)
Return 문(return statements)
함수에서 값을 돌려주는 방법, Go에서는 return 문 하나로 끝나요. 이 섹션에서는 그 return 문이 함수 F의 실행을 끝내고 선택적으로 결과 값을 하나 이상 제공하는 방식, 그리고 값이 많은 함수에서 결과를 돌려주는 세 가지 방법을 함께 살펴볼게요. 마지막에는 결과 파라미터의 초기값과 헷갈리기 쉬운 빈 표현식 제한까지 확인해 봐요.
출처: Go Specification
본문
함수 F 안의 return 문은 F의 실행을 끝내고, 선택적으로 결과 값을 하나 이상 제공해요. F가 호출자에게 돌아가기 전에 F가 defer한 함수들은 전부 먼저 실행됩니다.
ReturnStmt = "return" [ ExpressionList ] .
결과 타입이 없는 함수에서는 return 문이 어떤 결과 값도 지정해서는 안 돼요.
func noResult() {
return
}
결과 타입이 있는 함수에서 값을 돌려주는 방법은 세 가지가 있어요.
- 반환 값들을
return문에 명시적으로 나열하는 경우예요. 각 표현식은 단일 값을 가져야 하고, 함수 결과 타입의 해당 요소에assignable해야 합니다.
func simpleF() int {
return 2
}
func complexF1() (re float64, im float64) {
return -7.0, -4.0
}
return문의 표현식 리스트가 다중 값을 돌려주는 함수를 단 한 번 호출하는 경우예요. 그 효과는 그 함수가 돌려준 각 값을 각각의 타입을 갖는 임시 변수에 할당하고, 그다음 이 변수들을 나열하는return문을 두었을 때와 같아요. 이 시점부터는 앞의 경우 규칙이 그대로 적용되죠.
func complexF2() (re float64, im float64) {
return complexF1()
}
- 함수의 결과 타입이 결과 파라미터에 이름을 지정했다면 표현식 리스트가 비어 있어도 돼요. 결과 파라미터는 평범한 지역 변수처럼 동작하고, 함수는 필요에 따라 여기에 값을 할당할 수 있어요.
return문은 이 변수들의 값을 돌려주게 됩니다.
func complexF3() (re float64, im float64) {
re = 7.0
im = 4.0
return
}
func (devnull) Write(p []byte) (n int, _ error) {
n = len(p)
return
}
선언 방식과 무관하게, 모든 결과 값은 함수에 들어올 때 해당 타입의 zero values로 초기화돼요. 결과를 지정하는 return 문은 어떤 deferred 함수가 실행되기 전에 결과 파라미터를 설정합니다.
구현 제한(Implementation restriction)이 하나 있어요. 컴파일러는 return 위치에서 결과 파라미터와 같은 이름을 가진 다른 개체(상수, 타입, 변수)가 scope에 있다면 return 문의 빈 표현식 리스트를 허용하지 않을 수 있어요.
func f(n int) (res int, err error) {
if _, err := f(n-1); err != nil {
return // invalid return statement: err is shadowed
}
return
}
더 알아보기
deferred함수 실행 순서와 관련해서는 Defer statements를 함께 봐요.- 결과 값을 대입할 수 있는지 판단하는 규칙은 Assignability, 결과 파라미터의 역할은 Function types에서 다뤄요.
- 결과 값이 어떤 기본값으로 시작하는지 궁금하다면 The zero value, 그리고 이름 충돌이 일어나는 영역의 범위는 Declarations and scope를 확인해 보세요.