Menu
Coddy logo textTech

빈 인터페이스 (any)

Coddy GO 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨 — 107개 중 28번째.

빈 인터페이스(empty interface)는 메서드가 하나도 없는 인터페이스입니다. Go의 모든 타입은 최소한 0개의 메서드를 가지고 있으므로, 모든 타입은 자동으로 빈 인터페이스를 만족합니다. 이로 인해 빈 인터페이스는 어떤 타입의 값도 보유할 수 있습니다.

var anything interface{}

anything = 42
anything = "hello"
anything = true
anything = []int{1, 2, 3}

Go 1.18부터, any 키워드는 interface{}의 별칭으로 도입되었습니다. 이 둘은 완전히 상호 교환 가능하지만, any가 읽기에 더 깔끔합니다.

var value any = "Go is awesome"

빈 인터페이스(empty interface)는 알 수 없거나 다양한 타입의 값을 처리해야 할 때 유용합니다. fmt.Println과 같은 함수는 모든 타입의 인수를 허용하기 위해 이를 사용합니다:

func PrintAnything(v any) {
    fmt.Println("Value:", v)
}

func main() {
    PrintAnything(100)
    PrintAnything("text")
    PrintAnything(3.14)
}

하지만 트레이드오프가 있습니다. 값이 빈 인터페이스(empty interface)에 저장되면, 해당 값의 구체적인 타입 정보에 접근할 수 없게 됩니다.

기저 타입을 먼저 추출하지 않고는 메서드를 직접 호출하거나 필드에 접근할 수 없습니다. 다음 레슨에서는 타입 단언(type assertions)과 타입 스위치(type switches)를 사용하여 빈 인터페이스(empty interface)에서 구체적인 타입을 추출하는 방법을 다룰 것입니다.

challenge icon

챌린지

쉬움

빈 인터페이스를 사용하여 모든 유형의 값을 담을 수 있는 유연한 저장 컨테이너를 만들어 보겠습니다. any를 사용하여 동일한 구조체에 서로 다른 유형을 저장하는 방법을 보여주는 간단한 상자를 만들 것입니다.

코드는 두 개의 파일로 구성됩니다:

  • box.go: any 유형의 단일 필드 Content를 가진 Box 구조체를 정의합니다. 모든 유형의 값을 받아 해당 값을 포함하는 Box에 대한 포인터를 반환하는 NewBox 생성자 함수를 만듭니다. 상자에 저장된 내용을 보여주는 문자열을 반환하는 Describe 메서드를 추가합니다.
  • main.go: 입력에서 서로 다른 값을 읽고, 정수, 문자열, 불리언을 포함하는 상자들을 생성한 다음, 동일한 Box 유형이 어떻게 완전히 다른 값들을 가질 수 있는지 보여주기 위해 각 상자의 설명을 출력합니다.

다음 입력이 제공됩니다:

  • Line 1: 정수 값
  • Line 2: 문자열 값
  • Line 3: 불리언 값 (true 또는 false)

Describe 메서드는 다음 형식의 문자열을 반환해야 합니다:

Box contains: [value]

예를 들어, 42, hello, true가 주어지면 출력은 다음과 같아야 합니다:

Box contains: 42
Box contains: hello
Box contains: true

여기서 핵심은 any 유형이 모든 유형의 값을 수용하기 때문에 단일 Box 구조체가 정수, 문자열 또는 불리언을 저장할 수 있다는 점입니다. 각 상자는 서로 다른 것을 담고 있지만, 모두 동일한 Box 유형입니다.

치트 시트

빈 인터페이스(empty interface, interface{})는 메서드가 하나도 없는 인터페이스입니다. Go의 모든 타입은 최소한 0개의 메서드를 가지고 있으므로, 모든 타입은 자동으로 빈 인터페이스를 만족하며, 어떤 타입의 값이라도 담을 수 있습니다.

var anything interface{}

anything = 42
anything = "hello"
anything = true
anything = []int{1, 2, 3}

Go 1.18부터 interface{}의 별칭으로 any 키워드가 도입되었습니다. 이 둘은 완전히 상호 교환 가능하지만, any가 읽기에 더 깔끔합니다:

var value any = "Go is awesome"

빈 인터페이스는 알 수 없거나 다양한 타입의 값을 처리할 때 유용합니다. 함수는 모든 타입의 인수를 받을 수 있습니다:

func PrintAnything(v any) {
    fmt.Println("Value:", v)
}

func main() {
    PrintAnything(100)
    PrintAnything("text")
    PrintAnything(3.14)
}

트레이드오프(Tradeoff): 값이 빈 인터페이스에 저장되면, 해당 값의 구체적인 타입 정보에 대한 접근 권한을 잃게 됩니다. 타입 단언(type assertion)이나 타입 스위치(type switch)를 사용하여 내부 타입을 먼저 추출하지 않고는 메서드를 직접 호출하거나 필드에 접근할 수 없습니다.

직접 해보기

package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
)

func main() {
	reader := bufio.NewReader(os.Stdin)

	// 정수 값 읽기
	line1, _ := reader.ReadString('\n')
	intVal, _ := strconv.Atoi(strings.TrimSpace(line1))

	// 문자열 값 읽기
	line2, _ := reader.ReadString('\n')
	strVal := strings.TrimSpace(line2)

	// 불리언 값 읽기
	line3, _ := reader.ReadString('\n')
	boolVal, _ := strconv.ParseBool(strings.TrimSpace(line3))

	// TODO: NewBox를 사용하여 각 값에 대한 박스 생성
	// TODO: Describe 메서드를 사용하여 각 박스의 설명 출력

	// 컴파일 에러를 방지하기 위해 변수 사용 (구현 시 이 라인들을 제거하세요)
	_ = intVal
	_ = strVal
	_ = boolVal

	// 출력 형식 예시:
	// fmt.Println(box.Describe())
}
quiz icon실력 점검

이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.

객체 지향 프로그래밍의 모든 레슨