프로그래밍백엔드 개발자

Go에서 가변 인자 함수(변수 개수의 인자를 가지는 함수)가 어떻게 구현되는지 설명하세요. 올바르게 선언하고 호출하는 방법과 슬라이스 전송 시 발생할 수 있는 함정을 알려주세요.

Hintsage AI 어시스턴트로 면접 통과

답변

Go의 가변 인자 함수는 ... 문법을 통해 동일한 타입의 가변 인자를 받을 수 있습니다. 예를 들어:

func sum(nums ...int) int { total := 0 for _, num := range nums { total += num } return total }

이러한 함수를 호출할 때는 임의의 수의 인자를 전달할 수 있습니다:

result := sum(1, 2, 3, 4) // 10

또는 ... 문법을 사용하여 슬라이스를 전달할 수도 있습니다:

numbers := []int{1,2,3} result := sum(numbers...) // 6

세부사항:

  • 함수 내에서 가변 인자 파라미터는 슬라이스([]T)로 보입니다. 즉, 미리 준비된 슬라이스를 내부로 전달할 수 있습니다.
  • 이러한 파라미터는 항상 함수의 마지막 파라미터 리스트에 있어야 합니다.
  • ... 없이 슬라이스를 전달하면 함수는 일반 파라미터 타입인 []T를 기대하고, 가변 인자로 취급하지 않습니다.

트릭 질문

다음 코드의 결과는 무엇이며 그 이유는 무엇인가요?

func printInts(nums ...int) { fmt.Printf("%#v ", nums) } ints := []int{1, 2, 3} printInts(ints)

많은 사람들은 이 코드가 컴파일 될 것이라고 잘못 생각하지만, 실제로는 컴파일 오류가 발생합니다:

오류: 가변 인자 파라미터에 슬라이스를 ... 없이 전달할 수 없습니다.

정답:

printInts(ints...) // OK

주제에 대한 세부 사항을 모름으로 인해 발생한 실제 오류 사례


이야기

대규모 프로젝트에서 로깅 함수를 func Log(msgs ...string)으로 정의했습니다. 사전 준비된 문자열 슬라이스를 전달할 때 Log(strings)를 단순히 호출하여 로그 출력이 부정확하거나 런타임 패닉을 발생시켰습니다. 이유는 ...이 없어서 함수가 하나의 인자 타입인 []string으로 인식되었기 때문입니다.


이야기

유틸리티 함수 중 하나에서 여러 인자를 처리해야 했는데, 슬라이스가 포함되어 있었고 그 안에 더 많은 요소를 추가해야 했습니다. ...가 슬라이스의 복사본을 생성한다고 기대했으나 사실은 참조를 전달한 것이었고, 함수 내부에서 슬라이스를 변경했을 때 호출 측에 예상치 못한 영향을 미쳤습니다. 특히 원래 슬라이스가 재사용 가능한 버퍼였을 경우 더욱 그러했습니다.


이야기

개발자가 가변 인자 파라미터를 사용하여 집계 기능을 구현했지만, 한 동료가 캐스팅을 통한 호출 문법을 잘못 사용하여 sum(interface{}([]int)) 처럼 하여, 런타임 사소한 오류를 발생시켰습니다. 올바른 방법은 명시적으로 sum(slice...)를 사용하는 것이었습니다. 세부 사항에 대한 무지는 대규모 리팩터링 시 비직관적인 버그를 유발했습니다.