트랙
/
Go
Go
/
학습 과정
/
인터페이스
인터

인터페이스 에서 Go

2개의 연습 문제

인터페이스 소개

인터페이스는 메서드의 집합

가장 단순한 형태에서 인터페이스 타입은 메서드 시그니처의 집합이에요. 다음은 Add와 Value 두 메서드를 포함하는 인터페이스 정의의 예시예요:

type Counter interface {
    Add(increment int)
    Value() int
}

increment와 같은 매개변수 이름은 인터페이스 정의에서 생략할 수 있지만, 이름을 붙이면 가독성이 좋아지는 경우가 많아요.

Go에서 인터페이스 이름에는 Interface나 I라는 단어를 넣지 않아요. 대신 Reader, Stringer처럼 er로 끝나는 경우가 많아요.

인터페이스 구현하기

인터페이스의 메서드를 정의하는 타입은 자동으로, 암묵적으로 그 인터페이스를 "구현"해요. Go에는 implements 키워드가 없어요.

다음 타입은 위에서 본 Counter 인터페이스를 구현해요.

type Stats struct {
    value int
    // ...
}

func (s Stats) Add(v int) {
    s.value += v
}

func (s Stats) Value() int {
    return s.value
}

func (s Stats) SomeOtherMethod() {
    // The type can have additional methods not mentioned in the interface.
}

인터페이스를 구현하는 데에는 메서드가 값 리시버를 갖는지 포인터 리시버를 갖는지는 중요하지 않아요. (이 부분이 확실하지 않다면 메서드 개념을 다시 살펴봐요.)

인터페이스 타입의 값은 그 메서드들을 구현하는 어떤 값이든 담을 수 있어요. 1

즉, 이제 Counter 인터페이스를 기대하는 모든 곳에서 Stats를 사용할 수 있어요.

func SetUpAnalytics(counter Counter) {
    // ...
}

stats := Stats{}
SetUpAnalytics(stats)
// works because Stats implements Counter

함수의 매개변수와 반환 값이 모두 구체적인(즉, 인터페이스가 아닌) 타입을 써야 한다면, 재사용성은 크게 떨어질 거예요. 매개변수에 인터페이스 타입을 사용하면, 함수가 제 일을 하는 데 필요한 동작만 정의하면 돼요. 그러면 그 구체 타입들이 인터페이스만 구현하고 있다면, 서로 다른 구체 타입의 매개변수와 함께 함수를 사용할 수 있어요. 인터페이스 타입을 반환 값으로 쓸 때도 같은 논리가 적용돼요.

인터페이스는 암묵적으로 구현되기 때문에, 하나의 타입이 여러 인터페이스를 쉽게 구현할 수 있어요. 필요한 메서드만 모두 정의하면 돼요.

인터페이스 조합하기

인터페이스 정의에는 다른 인터페이스를 포함할 수 있어요. 다음은 표준 라이브러리에 있는 예시예요.

type ReadCloser interface {
	Reader
	Closer
}

// Based on these interfaces:

type Reader interface {
	Read(p []byte) (n int, err error)
}

type Closer interface {
	Close() error
}

ReadCloser를 정의할 때 Read와 Close의 메서드 시그니처를 반복해서 쓰는 대신, 인터페이스 정의는 기존의 Reader와 Closer 정의를 활용해요.

빈 인터페이스

Go에는 아주 특별한 인터페이스 타입이 하나 있는데, 메서드를 하나도 갖지 않는 빈 인터페이스 타입이에요. 빈 인터페이스는 interface{}처럼 써요. Go 1.18 이상에서는 any도 쓸 수 있어요. any는 별칭으로 정의되었어요.

빈 인터페이스에는 메서드가 없기 때문에, 모든 타입이 이를 암묵적으로 구현해요. 이는 어떤 값이든 일반적으로 받을 수 있는 함수를 정의할 때 유용해요. 이럴 때는 함수 매개변수에 빈 인터페이스 타입을 사용해요.

예를 들어:

func AnythingGoes(i interface{}) string {
    if i == 0 {
        return "zero"
    }
    if i == "" {
        return "empty string"
    }
    return "something else"
}
  1. Tour of Go: Interfaces ↩

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

인터페이스 배우기

연습이 잠겨 있어요

인터페이스 개념을 연습하려면 연습 문제 1개를 더 잠금 해제해요