2021. 5. 23. 00:41ㆍ개발/Golang
이번에는 상수에 대해 알아보겠습니다. 상수는 변하지 않는 값을 표현할때 사용합니다. 그래서 자주 사용되는 변경되지 않는 숫자값이나 문자열값에 주로 사용합니다.
1. 상수 선언
- 정수, 실수, 문자열 등 기본 타입값들만 상수로 선언이 가능합니다.
- 구조체, 배열 등 기본 타입이 아닌 타입에는 상수가 불가능 합니다.
- 상수가 가능한 타입
| 불리언 | 룬 |
| 정수 | 실수 |
| 복소수 | 문자열 |
const ConstValue int = 10
- const : 상수 선언 키워드
- ConstValue : 상수 명
- int : 타입
- 10 : 값
※ 상수명 규칙은 변수명과 같습니다. 첫 글자가 대문자인 상수는 패키지 외부로 공개되는 상수입니다. ( 16강에 설명 )
package main
import "fmt"
func main() {
const C int = 10 // 상수선언
var b int = C * 20
C = 20 // 에러 발생 - 상수는 대입문 좌변에 올수 없음
fmt.Println(&C) // 상수 주소 출력
}

- 상수는 값으로만 동작하기 때문에 에러가 발생합니다.
- &연산자를 변수앞에 사용하면 그 변수의 메모리 주솟값을 반환합니다. 하지만 상수 앞에 사용하면 상수의 메모리 주솟값을 접근 할 수 없기 때문에 출력하면 에러가 발생합니다.
- 변수는 값, 이름, 타입, 메모리주소 4가지 속성을 가지지만 상수는 값, 이름, 타입 3가지 속성만 가집니다.
2-1. 상수는 언제 사용하나?
- 상수로 변하지 않는 값에 이름을 부여하면 매번 값을 쓰지 않고 편리하게 이용할 수 있습니다.
- ex) 파이 같은 고정된 숫자를 사용할때 아주 유용함
package main
import "fmt"
func main() {
const PI1 float64 = 3.14592653589793238 // 상수
var PI2 float64 = 3.14592653589793238 // 변수
// PI1 = 4 //
PI2 = 4
fmt.Printf("원주율 : %f\n" , PI1)
fmt.Printf("원주율 : %f\n" , PI2)
}

2-2. 코드값으로 사용하기
- 코드값이란 어떤 숫자에 의미를 부여하는 것을 말합니다.
- 예를들어 ASCII 문자에서 A는 65지만 65와 A는 아무른 개연성이 없습니다. 그냥 약속을 한것입니다. 이와같이 HTTP
에서 200번은 OK 404은 NOT FOUND를 반환합니다. 숫자에 의미가 있다기보단 통신을 위해 숫자값에 의미를 부여한
것입니다.
- 프로그래밍에서도 코드값을 이용해야하는 경우가 많습니다.
package main
import "fmt"
// 상수값에 코드를 부여합니다.
const Pig int = 0
const Cow int = 1
const Chicken int = 2
// 코드값에 따라서 텍스틀 출력합니다.
func PrintAnimal(animal int) {
if animal == Pig {
fmt.Println("꿀꿀")
}else if animal == Cow {
fmt.Println("음메")
}else if animal == Chicken {
fmt.Println("꼬끼오")
}else{
fmt.Println("...")
}
}
func main(){
PrintAnimal(Pig)
PrintAnimal(Cow)
PrintAnimal(Chicken)
}

- Pig, Cow Chicken을 상수로 선언해서 나만의 코드값을 부여했습니다. PrintAnimal() 함수를 호출하여 동물에 해당하는 텍스트를 출력합니다.
2-3. iota로 간편하게 열거값 사용하기
- 코드값으로 사용하기 때문에 1,2,3.... 처럼 1씩 증가하도록 정의 할때 iota 키워드를 사용하면 편합니다.
- iota는 0부터 시작해 1씩 증가합니다.
const (
Red int = iota // 0
Blue int = iota //1
Green int = iota //2
)
- 상수 목록을 소괄호 ()로 묶오 iota를 사용하면 0부터 1씩 차례로 증가하며 값이 초기화가 됩니다.
- 만약 첫번째 값과 똑같은 규칙이 계속된다면 iota를 생략할수 있습니다.
몇가지의 예)
const (
C1 uint = iota + 1 // 1
C2 // 2
C3 // 3
// 비트플래그를 통한 iota
const (
BitFlag1 uint = 1 << iota // 1 = 1 << 0
BitFlag2 // 2 = 1 << 1
BitFlag3 // 4 = 1 << 2
BitFlag4 // 8 = 1 << 3
)
// iota가 소괄호를 벗어낫기에 초기화되서 다시시작
const (
A int = iota // 0
B // 1
)
3. 타입없는 상수
- 상수 선언시 타입을 지정하지 않아도 됩니다. 타입없는 상숫값은 타입이 정해지지 않는 상태로 사용됩니다.
package main
import "fmt"
const PI = 3.14 // 타입없는 상수
const FloatPI float64 = 3.14 //float64 타입 상수
fucn main() {
var a int = PI * 100 // 오류가 발생하지않음
var b int = FloatPI * 100 // 타입 오류가 발생
fmt.Println(a)
fmt.Println(b)
}
- PI값은 타입이 없기 때문에 3.14 숫자로만 동작합니다. FloatPI는 float64 타입 상수입니다.
- 타입 없는 상수는 변수에 복사될 때 타입이 정해지기 때문에 여러 타입에 사용되는 상숫값을 사용할 때 편리합니다.
4. 상수와 리터럴
- 컴퓨터에서 리터럴이란 고정된 값, 값 자체로 쓰인 문구라고 볼 수 있습니다.
var str string = "Hello World"
var i int = 0
i = 30
- Hello World, 0, 30 과 같이 고정된 값 자체로 쓰인 문구가 바로 리터럴 입니다.
- Go언어에서는 상수는 리터럴과 같이 취급합니다. 그래서 컴파일될 때 상수는 리터럴로 변환되어 실행파일에 쓰임
- 상수 표현식도 컴파일 타임에 실제 결괏값을 리터럴로 변환하기 때문에 계산에 CPU 자원을 사용하지 않습니다.
- 상수는 메모리 주솟값에 접근할 수 없습니다. 이유는 컴파일에 리터럴로 전환되어 값 형태로 쓰이기 때문입니다. 그래서 동적 할당 메모리 영역을 사용하지 않습니다 ( 변수와 다른 이유 )
'개발 > Golang' 카테고리의 다른 글
| 『Tucker의 Go 언어 프로그래밍』 스터디 요약 노트 : 10강 switch문 (0) | 2021.05.26 |
|---|---|
| 『Tucker의 Go 언어 프로그래밍』 스터디 요약 노트 : 9강 if문 (0) | 2021.05.24 |
| 『Tucker의 Go 언어 프로그래밍』 스터디 요약 노트 : 7강 함수 (0) | 2021.05.22 |
| 『Tucker의 Go 언어 프로그래밍』 스터디 요약 노트 : 6강 연산자 (2) (0) | 2021.05.21 |
| 『Tucker의 Go 언어 프로그래밍』 스터디 요약 노트 : 6강 연산자 (1) (0) | 2021.05.16 |