Skip to content

Go 상수

상수의 값은 런타임에 변경할 수 없으며, 일단 할당되면 수정할 수 없습니다. 값의 출처는 다음과 같습니다.

  • 리터럴
  • 다른 상수 식별자
  • 상수 표현식
  • 상수인 타입 변환
  • iota

상수는 기본 데이터 타입만 가능하며, 다음은 사용할 수 없습니다.

  • 기본 타입 이외의 다른 타입, 예: 구조체, 인터페이스, 슬라이스, 배열 등
  • 함수의 반환 값

상수의 값은 수정할 수 없으며, 그렇지 않으면 컴파일을 통과할 수 없습니다.

초기화

상수 선언에는 const 키워드가 필요하며, 상수 선언 시 반드시 값을 초기화해야 하고 상수의 타입은 생략할 수 있습니다. 예를 들어

go
const name string = "Jack" // 리터럴

const msg = "hello world" // 리터럴

const num = 1 // 리터럴

const numExpression = (1+2+3) / 2 % 100 + num // 상수 표현식

값을 지정하지 않고 선언만 하면 컴파일을 통과할 수 없습니다.

go
const name string

컴파일러 오류

missing init expr for name

상수를 일괄 선언할 때는 가독성을 높이기 위해 ()로 묶을 수 있으며, 여러 개의 ()를 사용하여 그룹 효과를 낼 수 있습니다.

go
const (
   Count = 1
   Name  = "Jack"
)

const (
   Size = 16
   Len  = 25
)

동일한 상수 그룹에서 값을 할당한 상수 뒤의 상수는 값을 할당하지 않아도 되며, 그 값은 기본적으로 이전 값과 동일합니다. 예를 들어

go
const (
  A = 1
  B // 1
  C // 1
  D // 1
  E // 1
)

iota

iota는 내장된 상수 식별자로, 일반적으로 상수 선언에서 무타입 정수 서수를 나타내는 데 사용되며, 일반적으로 괄호 안에서 사용됩니다.

go
const iota = 0

몇 가지 사용 사례를 살펴보겠습니다.

go
const (
   Num = iota // 0
   Num1 // 1
   Num2 // 2
   Num3 // 3
   Num4 // 4
)

이렇게 작성할 수도 있습니다.

go
const (
   Num = iota*2 // 0
   Num1 // 2
   Num2 // 4
   Num3 // 6
   Num4 // 8
)

또한

go
const (
   Num = iota << 2*3 + 1 // 1
   Num1 // 13
   Num2 // 25
   Num3 = iota // 3
   Num4 // 4
)

위의 몇 가지 예시를 통해 iota가 증가한다는 것을 알 수 있습니다. 첫 번째 상수가 iota 값의 표현식을 사용하면, 순번 값의 변화에 따라 자동으로 후속 상수에 할당되며, 새로운 const로 재설정될 때까지 계속됩니다. 이 순번은 실제로 코드의 상대 행 번호이며, 현재 그룹의 시작 행을 기준으로 한 상대 행 번호입니다. 아래 예시를 보겠습니다.

go
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 를 통해 열거형을 구현합니다. 아래는 간단한 예시입니다.

go
type Season uint8

const (
  Spring Season = iota
  Summer
  Autumn
  Winter
)

이러한 열거형은 실제로 숫자이며, Go 는 이를 문자열로 직접 변환하는 것을 지원하지 않지만, 사용자 정의 타입에 메서드를 추가하여 문자열 표현을 반환하고 Stringer 인터페이스를 구현할 수 있습니다.

go
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 은 사용자 정의 타입이므로 강제 타입 변환을 통해 다른 숫자도 해당 타입으로 변환할 수 있습니다.

    go
    Season(6)
  • 번거로움. 문자열 표현은 직접 구현해야 합니다.

  • 표현력이 약함. const 는 기본 데이터 타입만 지원하므로 이러한 열거형 값도 문자열과 숫자로만 표현할 수 있습니다.

왜 언어 차원에서 열거형을 지원하지 않는지笔者는 매우 이해할 수 없는 일입니다. 저는 이것이 분명히 득이 실보다 크다고 생각합니다.

Golang by www.golangdev.cn edit