트랙
/
Go
Go
/
연습 문제
/
공항 로봇
공항 로봇

공항 로봇

학습 연습 문제

소개

메서드 집합으로서의 인터페이스

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

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

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

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

인터페이스 구현하기

인터페이스의 메서드들을 정의한 타입은 자동으로, 암묵적으로 그 인터페이스를 "구현"해요. 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]

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

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

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

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

빈 인터페이스

Go에는 아주 특별한 인터페이스 타입이 하나 있는데, 메서드를 하나도 포함하지 않는 빈 인터페이스 타입이에요. 빈 인터페이스는 이렇게 써요: interface{}. any는 interface{}의 별칭이며, 더 흔히 사용돼요.

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

지침

베를린의 새 공항이 로봇 연구소를 위해 개발자들을 채용했고, 여러분은 그곳에서 일을 시작해요. 그곳에는 투박하고 어딘가 사람을 닮은 로봇들이 있는데, 공항에서는 이 로봇으로 고객 서비스를 개선하려고 해요.

첫 번째 업무는, 사람들이 셀프 체크인 카운터에서 여권을 스캔한 뒤 로봇이 그 사람의 모국어로 인사할 수 있게 하는 프로그램을 작성하는 거예요.

로봇은 자기 능력을 자랑스러워해서, 항상 자기가 할 수 있는 언어가 무엇인지 먼저 말하고 그다음에 인사를 해요. 예를 들어 누군가 독일 여권을 스캔하면 로봇은 이렇게 말해요:

I can speak German: Hallo Dietrich!

1. 추상적인 인사 기능 만들기

여러분이 직접 각 언어의 코드를 작성하지는 않아요. 그래서 나중에 다른 개발자들이 더 많은 언어를 쉽게 추가할 수 있도록 로봇의 코드를 구조화해야 해요.

먼저 Greeter 인터페이스를 두 개의 메서드와 함께 정의해요.

  • LanguageName은 로봇이 방문객에게 인사할 때 사용할 언어의 이름(string)을 반환해요.
  • Greet은 방문객의 이름(string)을 받아서, 특정 언어의 인사말이 담긴 string을 반환해요.

다음으로 함수 SayHello를 구현해요. 이 함수는 방문객의 이름과 Greeter 인터페이스를 구현한 무엇이든 인자로 받아서, 원하는 인사 문자열을 반환해요. 예를 들어, LanguageName이 "German"을 반환하고 Greet이 "Hallo {name}!"을 반환하는 독일어 Greeter 구현이 있다고 해봐요:

SayHello("Dietrich", germanGreeter)
// => "I can speak German: Hallo Dietrich!"

2. 이탈리아어 구현하기

이제 이탈리아 여권을 스캔한 사람들에게도 로봇이 작동하도록 만들 차례예요.

그러려면 Italian 구조체를 만들고, 이 구조체가 1번 작업에서 만든 Greeter 인터페이스를 충족하는 데 필요한 두 메서드를 구현해요. 이탈리아어로는 "Ciao {name}!"라고 인사하면 돼요.

3. 포르투갈어 구현하기

퇴근하기 전에, 포르투갈어로 인사하는 기능도 마무리해야 해요.

그러려면 Portuguese 구조체를 만들고, 여기에서도 이 구조체가 Greeter 인터페이스를 충족하는 데 필요한 두 메서드를 구현해요. 포르투갈어로는 "Olá {name}!"라고 인사하면 돼요.

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

공항 로봇 문제를 시작해 볼 준비가 됐나요?

Exercism에 가입하고 Go 트랙을 개념 34개연습 문제 165개, 그리고 실제 사람의 멘토링과 함께 배우고 익혀 보세요. 모두 무료예요.