프로그래밍에서는 int, string, UUID와 같은 기본 내장 타입 또는 라이브러리 제공 타입을 자주 사용함. 하지만 이처럼 일반적인 타입만 활용하면 실제 값이 무엇을 의미하는지 점차 망각하게 되고, 중대한 버그로 이어질 수 있음. 아무리 단순하거나 쉽게 보이는 값이라도, 목적에 따라 별도의 고유한 타입을 정의해서 사용하는 것이 훨씬 좋은 해결책임. 예를 들어 int나 string 등을 직접 전달하지 말고, 각 의미에 맞는 타입을 만드는 방식을 추천함. 타입 시스템은 코드 안전성을 지키는 강력한 도구임. 모델마다 고유의 ID 타입을 정의하고, float나 int 등만으로 인자를 처리하는 패턴을 피하는 것이 여러 버그를 예방하는 핵심임. 실제 시스템에서 서로 의미가 다른 int, string, UUID를 혼동해 생긴 버그 사례가 아주 많음. Go처럼 타입 시스템이 비교적 단순한 언어라도, 독립 타입만 잘 정의하면 이런 오동작을 원천적으로 차단할 수 있음. 오히려 이러한 방식을 사용하지 않는 것이 신기하게 느껴질 정도임. 코드 예시는 모두 GitHub에서 확인할 수 있음:
https://github.com/cdzombak/libwx_types_lab?ref=dzombak.com
타입 시스템의 중요성
예시: ID 타입 분리
type AccountID uuid.UUID
type UserID uuid.UUID
func UUIDTypeMixup() {
{
userID := UserID(uuid.New())
DeleteUser(userID)
// 에러 없음
}
{
accountID := AccountID(uuid.New())
DeleteUser(accountID)
// 에러: AccountID 타입을 UserID로 사용할 수 없음
}
{
accountID := uuid.New()
DeleteUserUntyped(accountID)
// 컴파일 타임 에러 없음, 런타임에 문제가 발생할 가능성 높음
}
}
libwx에서의 적용
코드 예시
// 화씨 온도 선언
temp := libwx.TempF(84)
// 상대습도 선언(퍼센트)
humidity := libwx.RelHumidity(67)
// 화씨 대신 섭씨 온도를 요구하는 함수에 잘못 전달
fmt.Printf("Dew point: %.1fºF\n",
libwx.DewPointC(temp, humidity))
// 컴파일러가 타입 mismatch 오류를 바로 검출
// temp (TempF 타입)는 TempC로 사용할 수 없음
// 함수에 인자 순서 잘못 전달
fmt.Printf("Dew point: %.1fºF\n",
libwx.DewPointF(humidity, temp))
// 컴파일러가 인자 타입 오류를 막아줌
결론