Go에는 암묵적으로 타입이 지정되지 않은 상수(untyped)와 명시적으로 타입이 지정된 상수(typed)라는 두 가지 종류의 상수가 있습니다. 이는 언어가 타입 시스템을 유연하고 안전하게 만들고, 컴파일러가 컴파일 시점에 오류를 식별하며, 허용된 곳에만 타입 변환을 보장하는 것과 관련이 있습니다.
문제는 프로그래머가 이 두 가지 범주를 구별하지 않고 상수의 동작에 의존할 때 발생하며, 이는 함수 및 인터페이스 선언에서의 타입 요구 사항을 간과하게 될 수 있습니다. 이는 타입 간 변환 오류, 예상치 못한 컴파일 오류 또는 함수 호출 시 예상치 못한 "튀는" 호환성 문제를 초래할 수 있습니다.
해결책은 다음과 같이 명확한 이해가 필요합니다:
const x int = 42) 이후에 이 상수를 사용하는 것은 지정된 타입으로 제한됩니다.코드 예시:
const Pi = 3.14 // 암묵적으로 타입이 지정됨 const Answer int64 = 42 // 명시적으로 타입이 지정됨 func printInt(a int) { fmt.Println(a) } func main() { printInt(Pi) // 오류: Pi는 int가 아님 (하지만 명시적으로 변환 가능) printInt(int(Pi)) // 괜찮음 printInt(Answer) // 괜찮음, 왜냐하면 Answer는 이미 int64이며, int64에서 int로의 변환은 명시적 변환임 }
주요 특징:
암묵적으로 타입이 지정된 상수를 int 타입의 변수에 부동 소수점 값으로 할당할 수 있나요?
아니요. 암묵적으로 타입이 지정된 상수는 다른 타입의 식에 사용될 수 있지만, float 상수를 int 타입의 변수에 할당하려고 하면 컴파일 오류가 발생합니다. 명시적 변환이 필요합니다:
const Pi = 3.14 var x int = Pi // 컴파일러 오류 발생 var y int = int(Pi) // 괜찮음
암묵적으로 타입이 지정된 상수는 첫 번째 할당 시점에 타입을 얻나요?
아니요, 상수는 특정 타입이 예상되는 컨텍스트에 삽입되거나 명시적으로 선언될 때까지 타입을 갖지 않습니다. 그 외의 경우에는 여전히 untyped입니다.
암묵적 타입의 큰 숫자 상수를 값이 맞는 경우 작은 크기의 변수 초기화에 사용할 수 있나요?
예, 절대값이 대상 타입의 범위 안에 있다면 가능합니다. 그렇지 않으면 컴파일러가 오버플로우 오류를 발생시킵니다.
예시:
const Big = 1 << 62 var x int32 = Big // 오류: Big이 int32에 맞지 않음 var y int64 = Big // 괜찮음
복잡한 금융 프로젝트에서 개발자들은 여러 상수(비율, 계수)를 암묵적으로 타입이 지정되지 않게 선언했습니다. 어느 날 일부 함수가 float32 대신 float64를 요구하게 되었습니다. 자동 타입 조정으로 인해 계산의 정확도가 손실되었지만 즉시 발견되지 않았습니다.
장점:
단점:
시스템의 다른 부분에서는 모든 상수가 명시적으로 타입 선언을 통해 정의되고 변환이 명시적으로 이루어졌습니다:
const Discount float64 = 0.05
장점:
단점: