우선 C/C++에서 상수를 만드는 키워드인 const
와 final
에 대해 간략히 정리해보자.
C/C++ const
의 역할
- 변수의 읽기전용 설정 = 상수화
- (C++) 멤버 함수의 멤버 변수 변경 금지
Java final
의 역할
- 변수의 읽기전용 설정 = 상수화
- 메서드의 오버라이딩 금지
- 클래스의 상속 금지
다른 것들은 같은 키워드를 사용할 뿐 상수라 부르지 않고, 사실 Go에는 없는 기능들이니 첫 번째 역할에 대해서만 살펴보자.
Go와의 확실한 구분을 위해 일부러 변수의 읽기전용화라 표현했다. C/C++, Java에서 상수는 변수를 만드는 것과 동일하게 이름과 타입을 정한 후 최초 한 번 값을 설정하면 읽기전용이 돼 변경이 불가능하다.
const int i = 10;
final int i = 10;
변수를 읽기전용화한 것이기 때문에 다음과 같은 문법은 당연하며 자연스럽다.
// c
struct MyStruct
{
int i;
};
const struct MyStruct my = {0};
변수를 만들 수 있으면 상수도 만들 수 있다.
이 당연했던 사실이 Go에서는 오해의 요인이 된다.
변수는 변수, 상수는 상수
위의 C 예처럼 Go에서 구조체를 상수로 만들어 보자.
package main
import "fmt"
type MyStruct struct {
i int
}
func main() {
const my MyStruct = MyStruct{10}
fmt.Println(my.i)
}
이 코드는 다음과 같은 오류가 발생한다.
./main.go:10:8: const initializer MyStruct literal is not a constant
이와 같이 Go에서는 타입이라고 해서, 즉 변수를 만들 수 있다고 해서, 상수를 만들 수 있는 것은 아니다. Go가 지원하는 상수의 종류는 boolean, rune, integer, floating-point, complex, string 등 6가지 밖에 없다. Go spec.의 관련 내용은 다음과 같다.
There are boolean constants, rune constants, integer constants, floating-point constants, complex constants, and string constants. Rune, integer, floating-point, and complex constants are collectively called numeric constants.
정수형 상수의 내부 처리에서 확인한 것처럼 정수형 상수라고 해서 그 타입도 int
가 되는 것은 아니다. 즉, Go에서 상수는 읽기전용 변수가 아니라 그냥 상수인 것이다.
Go spec.에 상수에 대한 구현 요구사항이 있으니 마지막으로 확인하고 마무리하자.
Implementation restriction: Although numeric constants have arbitrary precision in the language, a compiler may implement them using an internal representation with limited precision. That said, every implementation must:
- Represent integer constants with at least 256 bits.
- Represent floating-point constants, including the parts of a complex constant, with a mantissa of at least 256 bits and a signed binary exponent of at least 16 bits.
- Give an error if unable to represent an integer constant precisely.
- Give an error if unable to represent a floating-point or complex constant due to overflow.
- Round to the nearest representable constant if unable to represent a floating-point or complex constant due to limits on precision.
These requirements apply both to literal constants and to the result of evaluating constant expressions.