트랙
/
Go
Go
/
학습 과정
/
다중 반환 값
다중

다중 반환 값 에서 Go

{other: "%{count}개의 연습 문제"}

다중 반환 값 소개

Go 함수와 메서드는 여러 값을 반환할 수 있어요:

func GetCard() (Card, error) { ... }

모든 반환 값은 순서대로 대입해야 하고, 쉼표로 구분해요:

card, err := GetCard()

빈 식별자

대입문의 각 위치는 변수를 하나씩 선언해요. Go에서는 변수를 선언해 놓고 사용하지 않으면 안 돼요. 변수 이름 대신 빈 식별자 _를 사용하면 그 반환 값을 건너뛸 수 있어요.

card, _ := GetCard() // error intentionally ignored
_, err := GetCard()  // card ignored, only checking for error

오류 처리

error는 내장 인터페이스예요. nil 오류는 오류가 발생하지 않았다는 뜻이고, nil이 아닌 값은 뭔가 잘못됐다는 뜻이에요. 관례적으로, 실패할 수 있는 함수는 마지막 값으로 error를 반환해야 해요. 호출하는 쪽은 다른 반환 값을 사용하기 전에 반드시 이 오류를 확인해야 해요:

card, err := GetCard()
if err != nil {
    // unsafe to use card here
    return err
}
// safe to use card here

콤마 오케이 관용구

두 값을 대입하는 패턴은 error 처리 밖에서도 나타나요. 맵 조회, 타입 어설션, 채널 수신은 모두 두 번째 불리언 값으로 성공 여부나 데이터의 존재 여부를 나타내는데, 이 값은 관례적으로 ok라고 불러요:

m := map[string]int{"a": 1}
v, ok := m["a"] // ok is true
v, ok = m["z"]  // ok is false
var i interface{} = "hello"
v, ok := i.(string) // ok is true
v, ok = i.(int)     // ok is false
v, ok := <-ch // ok is false if ch is closed and empty

이름 있는 반환 값

반환 값에는 함수 시그니처에서 이름을 붙일 수도 있어요. 그러면 이 변수들을 함수 본문 안에서 사용할 수 있어요.

func divide(a, b int) (quotient, remainder int) {
    quotient = a / b
    remainder = a % b
    return quotient, remainder
}

이름 있는 반환 값은 각 반환 위치가 무엇을 의미하는지 알려 줘요. 값을 쓰지 않고 작성하는 return, 즉 값 없는 return과 함께 사용할 수도 있어요. 값 없는 return은 이름 있는 변수의 현재 값을 암묵적으로 반환해요:

func split(sum int) (x, y int) {
    x = sum * 4 / 9
    y = sum - x
    return
}

함수가 길어지면 값 없는 return은 무엇을 반환하는지 분명하지 않아서 가독성을 해치는 경우가 많아요. 시그니처가 항상 눈에 들어올 만큼 함수가 짧지 않다면 반환 값을 명시적으로 쓰는 편이 좋아요.

더 알아보려면 Go by Example: Multiple Return Values, Effective Go: Multiple Returns, Tour of Go를 확인해 봐요.

GitHub에서 편집 링크가 새 창이나 탭에서 열려요