상수 선언(Constant declarations)
상수 선언(Constant declarations)
Go에서 값을 한 번 정하면 바꾸고 싶지 않을 때가 있어요. 그럴 때 쓰는 게 바로 상수 선언이에요. 상수 선언은 식별자 목록(상수의 이름들)을 상수 표현식 목록의 값에 묶어주는 역할을 해요. 이때 식별자의 개수는 반드시 표현식의 개수와 같아야 하고, 왼쪽의 n번째 식별자는 오른쪽의 n번째 표현식 값에 묶여요.
출처: Go Specification
본문
상수 선언의 문법(EBNF)은 이렇게 생겼어요.
ConstDecl = "const" ( ConstSpec | "(" { ConstSpec ";" } ")" ) .
ConstSpec = IdentifierList [ [ Type ] "=" ExpressionList ] .
IdentifierList = identifier { "," identifier } .
ExpressionList = Expression { "," Expression } .
하나씩 뜯어볼게요. ConstSpec을 보면 Type과 "=" ExpressionList가 대괄호로 둘러싸여 있는데요, 즉 타입과 표현식이 있을 수도 없을 수도 있어요. 각각의 경우가 어떻게 달라지는지 볼게요.
타입이 명시되어 있으면 모든 상수가 그 타입을 갖고, 표현식 값들은 그 타입에 할당 가능(assignable)해야 해요. 이때 타입은 타입 매개변수(type parameter)가 되면 안 돼요. 반면 타입을 생략하면 각 상수는 대응하는 표현식의 개별 타입을 그대로 가져요.
표현식 값들이 타입 없는(untyped) 상수라면, 선언된 상수도 타입 없는 상태로 남고 상수 식별자는 그 상수 값을 가리켜요. 예를 들어 표현식이 부동소수점 리터럴이라면, 리터럴의 소수부가 0이어도 상수 식별자는 부동소수점 상수를 가리켜요. 실제 예시를 볼게요.
const Pi float64 = 3.14159265358979323846
const zero = 0.0 // untyped floating-point constant
const (
size int64 = 1024
eof = -1 // untyped integer constant
)
const a, b, c = 3, 4, "foo" // a = 3, b = 4, c = "foo", untyped integer and string constants
const u, v float32 = 0, 3 // u = 0.0, v = 3.0
zero = 0.0처럼 소수부가 0인 리터럴이라도 타입을 붙이지 않으면 타입 없는 부동소수점 상수로 남는다는 점이 포인트예요. 주석에서 볼 수 있듯 a, b, c = 3, 4, "foo"는 식별자마다 각각 3, 4, "foo"라는 서로 다른 타입의 값에 묶여요.
이번에는 괄호로 묶은 const 선언 목록에서 한 가지 멋진 규칙이 있어요. 첫 번째 ConstSpec을 제외하고는 표현식 목록을 생략할 수 있답니다. 이렇게 비워 둔 목록은, 바로 앞에서 가장 먼저 나온 비어 있지 않은 표현식 목록과 그 타입(있다면)을 텍스트 그대로 치환한 것과 똑같아요. 표현식 목록을 생략하는 건 곧 이전 목록을 반복하는 것과 같으니, 식별자의 개수는 이전 목록의 표현식 개수와 같아야 해요.
이 메커니즘은 iota 상수 생성기와 함께 쓰면 연속된 값들을 아주 가볍게 선언할 수 있어요.
const (
Sunday = iota
Monday
Tuesday
Wednesday
Thursday
Friday
Partyday
numberOfDays // this constant is not exported
)
Sunday = iota에 iota가 0부터 시작하고, 표현식 목록을 생략한 나머지 행은 이전 목록을 반복하니까 Monday, Tuesday...가 자동으로 1, 2, ... 값을 갖게 돼요. 이 iota의 동작은 다음 절에서 자세히 다룰게요.
더 알아보기
- Constant expressions — 상수 표현식이 어떻게 만들어지는지, 이 선언이 묶는 값이 어디서 오는지 다뤄요.
- Iota — 위에서 만난 연속 값 선언의 핵심,
iota상수 생성기를 자세히 봐요. - Constants — 타입 없는 상수가 정확히 뭘 의미하는지에 대한 배경 설명이에요.
- Assignability — "타입에 할당 가능해야 한다"는 조건의 정확한 기준이에요.
- Variable declarations — 값을 바꿀 수 있는 변수 선언과 어떻게 다른지 비교해 보면 좋아요.