Go 상수
상수의 값은 런타임에 변경할 수 없으며, 일단 할당되면 수정할 수 없습니다. 값의 출처는 다음과 같습니다.
- 리터럴
- 다른 상수 식별자
- 상수 표현식
- 상수인 타입 변환
- iota
상수는 기본 데이터 타입만 가능하며, 다음은 사용할 수 없습니다.
- 기본 타입 이외의 다른 타입, 예: 구조체, 인터페이스, 슬라이스, 배열 등
- 함수의 반환 값
상수의 값은 수정할 수 없으며, 그렇지 않으면 컴파일을 통과할 수 없습니다.
초기화
상수 선언에는 const 키워드가 필요하며, 상수 선언 시 반드시 값을 초기화해야 하고 상수의 타입은 생략할 수 있습니다. 예를 들어
const name string = "Jack" // 리터럴
const msg = "hello world" // 리터럴
const num = 1 // 리터럴
const numExpression = (1+2+3) / 2 % 100 + num // 상수 표현식값을 지정하지 않고 선언만 하면 컴파일을 통과할 수 없습니다.
const name string컴파일러 오류
missing init expr for name상수를 일괄 선언할 때는 가독성을 높이기 위해 ()로 묶을 수 있으며, 여러 개의 ()를 사용하여 그룹 효과를 낼 수 있습니다.
const (
Count = 1
Name = "Jack"
)
const (
Size = 16
Len = 25
)동일한 상수 그룹에서 값을 할당한 상수 뒤의 상수는 값을 할당하지 않아도 되며, 그 값은 기본적으로 이전 값과 동일합니다. 예를 들어
const (
A = 1
B // 1
C // 1
D // 1
E // 1
)iota
iota는 내장된 상수 식별자로, 일반적으로 상수 선언에서 무타입 정수 서수를 나타내는 데 사용되며, 일반적으로 괄호 안에서 사용됩니다.
const iota = 0몇 가지 사용 사례를 살펴보겠습니다.
const (
Num = iota // 0
Num1 // 1
Num2 // 2
Num3 // 3
Num4 // 4
)이렇게 작성할 수도 있습니다.
const (
Num = iota*2 // 0
Num1 // 2
Num2 // 4
Num3 // 6
Num4 // 8
)또한
const (
Num = iota << 2*3 + 1 // 1
Num1 // 13
Num2 // 25
Num3 = iota // 3
Num4 // 4
)위의 몇 가지 예시를 통해 iota가 증가한다는 것을 알 수 있습니다. 첫 번째 상수가 iota 값의 표현식을 사용하면, 순번 값의 변화에 따라 자동으로 후속 상수에 할당되며, 새로운 const로 재설정될 때까지 계속됩니다. 이 순번은 실제로 코드의 상대 행 번호이며, 현재 그룹의 시작 행을 기준으로 한 상대 행 번호입니다. 아래 예시를 보겠습니다.
const (
Num = iota<<2*3 + 1 // 1 첫 번째 행
Num2 = iota<<2*3 + 1 // 13 두 번째 행
_ // 25 세 번째 행
Num3 //37 네 번째 행
Num4 = iota // 4 다섯 번째 행
_ // 5 여섯 번째 행
Num5 // 6 일곱 번째 행
)예시에서 익명 식별자 _ 를 사용하여 한 줄의 위치를 차지했으며, iota 의 값은 본질적으로 iota 가 있는 행과 현재 const 그룹의 첫 번째 행과의 차이임을 알 수 있습니다. 서로 다른 const 그룹은 서로 영향을 주지 않습니다.
열거형
Go 언어는 열거형을 위해 별도의 데이터 타입을 설계하지 않았습니다. 다른 언어와 달리 일반적으로 enum 을 사용하여 나타냅니다. 일반적으로 Go 에서는 사용자 정의 타입 + const + iota 를 통해 열거형을 구현합니다. 아래는 간단한 예시입니다.
type Season uint8
const (
Spring Season = iota
Summer
Autumn
Winter
)이러한 열거형은 실제로 숫자이며, Go 는 이를 문자열로 직접 변환하는 것을 지원하지 않지만, 사용자 정의 타입에 메서드를 추가하여 문자열 표현을 반환하고 Stringer 인터페이스를 구현할 수 있습니다.
func (s Season) String() string {
switch s {
case Spring:
return "spring"
case Summer:
return "summer"
case Autumn:
return "autumn"
case Winter:
return "winter"
}
return ""
}이렇게 하면 간단한 열거형이 구현됩니다. 공식 도구 Stringer 를 사용하여 열거형을 자동으로 생성할 수도 있습니다.
하지만 다음과 같은 단점이 있습니다.
타입 안전하지 않음.
Season은 사용자 정의 타입이므로 강제 타입 변환을 통해 다른 숫자도 해당 타입으로 변환할 수 있습니다.goSeason(6)번거로움. 문자열 표현은 직접 구현해야 합니다.
표현력이 약함.
const는 기본 데이터 타입만 지원하므로 이러한 열거형 값도 문자열과 숫자로만 표현할 수 있습니다.
왜 언어 차원에서 열거형을 지원하지 않는지笔者는 매우 이해할 수 없는 일입니다. 저는 이것이 분명히 득이 실보다 크다고 생각합니다.
