컴파일되는 JavaScript
개인적으로는 golang(고랭, 고언어)을 컴파일되는 JavaScript라고 생각한다.
golang에는 드러나지 않는 곳에서 많은 것을 처리하는 golang 런타임(JavaScript 인터프리터에서 파생된 무엇?)이 숨어있다. 그리고 golang 컴파일러는 golang 런타임을 뜯어서 큰 힘 들이지 않고 쉽게 만든 것 같다 (이건 칭찬이다). golang은 아름다움보다는 실용성을 추구한 언어다. 그게 golang의 매력이다.
같은듯 다른 '객체 (Object)'
c++ 같은 OOP 언어에서 객체는 변수와 메소드의 덩어리다. 그리고 type이다. c++로 객체지향 프로그래밍을 한다는 것은 달리 말하면 type을 정의하는 일이다.
반면, JavaScript에서 객체는 key-value 테이블이다. 그리고 instance다. JS Object를 딱히 type이라고 부르기 어려운 것이 JavaScript에서는 JS Object 아닌 것이 없기 때문이다. int도 JS Object이고, string도 JS Object이고, 심지어 function도 JS Object다.
다형성을 책임지는 interface 타입
golang은 type을 철저하게 체크한다. 하지만 JavaScript보다 조금 더 엄격한 정도다.
golang 코드의 interface 타입은 컴파일 시점에 결정되지 않는다. 실행 시점에 golang 런타임이 interface 타입을 체크한다 (즉, interface 타입 변수가 interface로서 갖춰야할 method 들을 구비하고 있는지 체크한다).
"Essential Go" 책의 설명을 참조하자.
https://essential-go.programming-books.io/reflection-c7fea6b176b74c54ab35f2d8fdd56f13
Go는 정적 타입 랭귀지다. 대부분의 경우 변수의 타입은 컴파일 시점에 알 수 있다. 하지만 interface 타입은 예외다. interface 타입 뒤에 있는 값이 실제 무슨 타입인지 컴파일 시점에는 알 수 없다.
요약하면 다음과 같다.
- interface 타입으로 어떤 method가 필요한지 규격을 정의할 수 있다.
- struct 타입으로 필요한 method를 구현할 수 있다.
- 어떤 struct가 어떤 interface 규격을 만족시키는지 언어적으로는 명시하지 않는다 (명시할 수 없다). golang 런타임이 실행 시점에 체크한다.
샘플코드 - interface 타입을 이용한 다형성 구현
상이한 타입의 변수들을 단일한 interface로 일관성있게 다루는 것이 다형성의 매력이다.
package main
import (
"fmt"
)
type writer interface {
write()
}
type koreanWriter struct{}
func (k koreanWriter) write() {
fmt.Println("안녕하세요")
}
type englishWriter struct{}
func (e englishWriter) write() {
fmt.Println("Hello")
}
func main() {
kw := koreanWriter{}
ew := englishWriter{}
wa := []writer{kw, ew}
for _, iw := range wa {
iw.write()
//
// 상이한 타입의 변수들을 단일한 interface로
// 일관성있게 다루는 것이 다형성의 매력
//
}
}