Duck Typing
"In other words, don't check whether it IS-a duck: check whether it QUACKS-like-a duck, WALKS-like-a duck, etc, etc, depending on exactly what subset of duck-like behaviour you need to play your language-games with."
- 사람이 오리처럼 행동하면 오리로 봐도 무방하다는 것이 덕 타이핑
- 장점
- 타입에 대해 매우 자유로움 → 어떤 값이 어떤 특징 타입을 갖는지 관심이 없는 경우
- 런타임 데이터를 기반으로 한 기능과 자료형을 창출함
- 단점
- 런타임 자료형 오류가 발생할 수 있음. 런타임 시에 예상치 못한 유형의 값이 있을 수 있음 → 해당 자료형에 무의미한 작업이 적용될 수 있음
- 이러한 오류가 오랜 시간 이후 발견될 수 있음, 버그 찾기 어려울 수 있음
- Static + Dynamic Language
- Go는 컴파일 기반의 정적 Type 언어이다. 하지만 동적 언어의 특성 또한 수용해서 동적 언어 스타일의 코딩이 가능하다.
- 즉 컴파일러의 보장을 받으면서 동적 언어의 장점을 사용할 수 있다는 것.
- 이를 가능하게 해주는 것이 바로 덕 타이핑 방식으로 작동하는 Go의 인터페이스
- Go에서 인터페이스의 역할은 객체의 동작을 표현하는 것이고, 인터페이스가 표현한 대로 동작하는 객체는 인터페이스를 사용할 수 있다.
- 정적 언어의 경우 특정 인터페이스를 사용하기 위해서는 명시적 키워드를 사용하여야 한다. (ex) Java-implements) 하지만 Go 에선 단지 원하는 인터페이스의 동작을 구현한 것 만으로 해당 인터페이스를 사용한 것이 된다.
- 많은 컴파일 언어에서는 특정 라이브러리나 프레임워크와 호환되는 객체를 만드려면 특정 인터페이스를 구현하거나 클래스를 상속받아 구현하는 것이 일반적이고 이렇게 생성된 클래스는 특정 라이브러리나 프레임워크와 강한 연결고리가 형성되기에 변경이나 확장에 용이하지 않음
- 반면 Go 에서는 덕 타이핑 방식으로 작동하는 인터페이스를 통해 다형성을 지원하고 있고, 이런 특징 덕에 정적 Type 언어임에도 불구하고 모듈간 결합도가 낮고 확장하기 쉬운 이점을 가지고 있다.
//인터페이스 선언
type Duck interface {
Quack() string
Walk() string
}
//Swan 구조체 선언 및 Duck 인터페이스의 메소드 구현
type Swan struct {
//Duck interface를 구현한다는 명시적 keyword가 없다
}
//Duck interface 의 메소드를 구현함 1
func (s Swan) Quack() string {
return "백조 울음소리"
}
//Duck interface 의 메소드를 구현함 2
func (s Swan) Walk() string {
return "백조 걷는 모습"
}
//Chicken 구조체 선언 및 Duck 인터페이스의 메소드 구현
type Chicken struct {
//Duck interface를 구현한다는 명시적 keyword가 없다
}
//Duck interface 의 메소드를 구현함 1
func (c Chicken) Quack() string {
return "닭 울음소리"
}
//Duck interface 의 메소드를 구현함 2
func (c Chicken) Walk() string {
return "닭 걷는 모습"
}
//깜짝 놀라면 울고 난 후 걷는다(도망)
func Scare(duck Duck) {
//Duck의 동작을 구현한 어떤 객체라도 argument로 전달 될 수 있다.
fmt.Println(duck.Quack())
fmt.Println(duck.Walk())
}
func main() {
var swan Duck = Swan{}
Scare(swan)
chicken := Chicken{}
Scare(chicken)
human := struct {
}{}
Scare(human) //에러
//일반적인 동적 언어라면 실행 시점에서 에러가 발생하겠지만, Go는 컴파일 타임이 존재하므로
//에러가 발생해 실행조차 할 수 없다.
//Cannot use 'human' (type struct{}) as the type Duck
//Type does not implement 'Duck' as some methods are missing:
//Quack() string Walk() string
}
Share article