변수와 타입 — Ruby의 동적 타이핑이 그리워지는 순간
duck typing이 사라진 세계에서 살아남기
Ruby에서 변수를 만들 때 타입을 신경 쓴 적이 있는가? 없다. name = "hello"하면 알아서 String이다. name = 42로 바꿔도 아무도 뭐라 안 한다. 런타임이 알아서 처리한다.
Go는 다르다. var name string = "hello" — 타입을 명시한다. 짧게 쓰면 name := "hello"인데, 이래도 Go 컴파일러가 타입을 추론해서 고정한다. 한번 string이면 영원히 string이다. name = 42 하면 컴파일 에러.
:= 가 Ruby의 = 과 다른 점
Ruby의 =는 아무 값이나 재할당 가능하다. Go의 :=는 선언+초기화를 한 번에 하지만, 이후 타입이 바뀔 수 없다. Ruby에서 x = []; x = {}가 되는 건 Go에서는 불가능하다.
제로값(Zero Value) — nil 대신
Ruby에서 초기화 안 한 변수는 nil이다. Go에서는 타입별 제로값이 정해져 있다. int는 0, string은 "", bool은 false, 포인터는 nil. Ruby의 nil 하나로 통일되는 세계가 오히려 단순해 보일 수 있다.
타입 변환이 자동이 아니다
Ruby에서 "count: " + 42.to_s — .to_s 붙이면 된다. Go에서는 "count: " + strconv.Itoa(42) — 명시적 변환 필수. int와 float64 사이도 자동 변환 안 된다. var a int = 1; var b float64 = float64(a) 이렇게 해야 한다.
귀찮은가? 귀찮다. 근데 Ruby에서 "5" + 3이 TypeError 나는 걸 프로덕션에서 겪어본 사람은 Go의 엄격함이 오히려 편하게 느껴질 거다.
Ruby에서 Go로
Ruby: 동적 타이핑, 변수에 아무 값이나 재할당 가능 → Go: 정적 타이핑, 한번 정한 타입은 변경 불가
Ruby: nil 하나로 통일 → Go: 타입별 제로값 (int=0, string="", bool=false)
Ruby: .to_s, .to_i로 간편 변환 → Go: strconv 패키지로 명시적 변환 필수
:= 는 선언+초기화 단축. 함수 안에서만 사용 가능 (패키지 레벨은 var 필수)
장점
- ✓ 컴파일 타임에 타입 에러를 전부 잡아준다 — Ruby의 "프로덕션에서 발견" 패턴이 사라짐
- ✓ := 단축 문법으로 타입 명시 없이도 사용 가능 — 생각보다 덜 귀찮다
단점
- ✗ 타입 변환이 전부 명시적 — Ruby의 .to_s 한 방에 비하면 코드가 길어진다
- ✗ Generic이 1.18에서야 추가됨 — 타입 시스템이 성숙하지 않은 부분이 있다