상수 선언
상수란 변하지 않는 값을 뜻한다. 문자열, 정수, 실수 등 기본 타입값들만 상수로 선언될 수 있다.
구조체, 배열 등 기본 타입(primitive)이 아닌 타입(complex)에는 상수를 사용할 수 없다.
Go lang 상수 가능 타입.
불리언, 정수, 복소수, 룬(rune), 실수, 문자열
상수 선언 방식은 const
키워드를 사용한다.
const ConstValue int = 1
상수의 메모리 주솟값을 접근할 수 없기 때문에 &(메모리 주솟값을 반환함)를 이용해서 출력하면 에러가 발생한다.
상수는 값, 이름, 타입 3가지 속성만을 가진다. 일반 변수는 값, 이름 타입, 메모리 주소 4가지 속성을 가진다.
상수의 사용
변하면 안 되는 값
변하면 안되는 상수 예를 들어 원주율 파이값을 사용할 때와 같이 용한다.
코드값으로 사용하기
상수를 코드값으로 사용할 수 있다. 어떤 숫자에 의미를 부여하는 것을 말한다. 예를 들어 ASII 문자 코드가 있다.
iota로 간편하게 열거값 사용하기
코드값으로 사용하기 때문에 값이 1, 2, 3.. 처럼 1씩 증가하도록 정의할 때 iota
키워드를 사용하면 편리하다.
const (
Red int = iota // 0
Blue int = iota // 1
Green int = iota // 2
)
상수 목록을 const와 소괄호로 묶고 iota를 사용하면 0부터 1씩 차례로 증가하며 값이 초기화 된다. 첫 번째 값과 똑같은 규칙이 계속 적용된다면 타입과 iota를 생략할 수 있다.
const (
C1 uint = iota + 1 // 1 = 0 + 1
C2 // 2 = 1 + 1
C3 // 3 = 2 + 1
)
C2는 타입과 iota를 생략하여 C1과 마찬가지로 C2 uint = iota + 1이 적용된다.
const (
BitFlag1 uint = 1 << iota // 1 = 1 << 0
BitFlag2 // 2 = 1 << 1
BitFlag3 // 4 = 1 << 2
BitFlag4 // 8 = 1 << 3
)
const (
A int = iota // 0
B // 1
)
iota는 소괄호를 벗어나면 초기화되기 때문에 A는 0이다.
타입 없는 상수
상수 선언 시 타입을 명시하지 않을 수 있다. 타입 없는 상숫값은 타입이 정해지지 않은 상태로 사용된다.
package main
import "fmt"
const PI = 3.14 // 타입 없는 상수
const FloatPI float64 = 3.14 // float64 타입 상수
func main() {
var a int = PI * 100 // 오류가 발생하지 않음
var b int = FloatPI * 100 // 타입 오류 발생
fmt.Println(a) // 314
fmt.Println(b)
// cannot use FloatPI * 100 (type float64) as type int in assignment
}
float64 타입에 100을 곱하는 연산을 수행할 수 없다. 타입 불일치로 인한 에러 발생
상수와 리터럴
컴퓨터에서 리터럴이란 고정된 값, 값 자체로 쓰인 문구
var str string = "Hello World"
var i int = 0
i = 30
위 코드에서 "Hello World", 0, 30과 같이 고정된 값 자체로 쓰인 문구가 리터럴이다. Go 언어에서 상수는 리터럴과 같이 취급한다. 때문에 컴파일될 때 상수는 리터럴로 변환되어 실행 파일에 쓰인다.
상수 표현식 역시 컴파일 타임에 실제 결괏값 리터럴로 변환하기 때문에 상수 표현식 계산에 CPU 자원을 사용하지 않는다.
const PI = 3.14
var a int = PI * 100
위의 코드는 컴파일 타임에 다음으로 변환된다.
var a int = 314
상수의 메모리 주솟값에 접근할 수 없는 이유가 바로 여기에 있다. 컴파일 타임에 리터럴로 전환되어 실행 파일에 값 형태로 쓰이기 때문이다. 동적 할당 메모리 영역을 상용하지 않는다.
프로그램이 로드될 때 실행 파일이 올라간 영역을 코드 영역이라 하고 프로그램 실행을 위해서 실행 중 할당해서 사용되는 영역을 동적 할당 메모리 영역이라고 한다. 상수는 리터럴 코드 영역에 포함되기 때문에 동적 메모리 할당 영역을 사용하지 않는다.