Quick Syntax
var name string
var count = 3
ready, retries := true, 3
const (
maxRetries = 5
kib = 1 << (10 * iota)
)Go 변수 선언은 명시 선언, 짧은 선언, 상수, zero value를 나눠서 읽으면 헷갈림이 줄어듭니다.
문법
타입을 명시하는 var
var name string
var count int = 3var는 타입을 명시하거나, 초기값에서 타입을 추론하게 만들 수 있습니다. 초기값이 없으면 타입의 zero value가 들어갑니다.
var enabled bool // false
var total int // 0
var title string // ""함수 안의 짧은 선언 :=
count := 3
name := "refdock":=는 함수 안에서만 쓸 수 있습니다. 타입은 오른쪽 값에서 추론됩니다.
func run() {
ready := true
_ = ready
}패키지 최상위에서는 :=를 쓸 수 없습니다.
같은 블록에서 :=를 다시 쓸 때는 왼쪽 이름 중 적어도 하나가 새 변수여야 합니다. 모두 이미 있으면 대입문 =을 씁니다.
count, ok := 3, true // 둘 다 새 변수
count, ok = 4, false // 둘 다 이미 있으므로 =
next, ok := 5, true // next가 새 변수이므로 := 가능
_ = next안쪽 블록의 :=는 바깥 변수와 같은 이름이라도 새 변수를 만들 수 있습니다. 특히 err를 안쪽에서 다시 선언하면 바깥 err에 오류를 저장했다고 착각하기 쉬우므로, 짧은 선언은 가능한 한 바로 검사하는 흐름에 둡니다.
상수는 const
const timeoutSeconds = 5
const serviceName = "api"const는 컴파일 타임 상수입니다. 문자열, 숫자, bool 같은 상수 값에 사용합니다.
const maxRetries = 3 // untyped constant
const timeout time.Duration = 3 * time.Second
const (
flagRead = 1 << iota
flagWrite
flagAdmin
)타입을 쓰지 않은 상수는 문맥에 맞는 타입으로 변환될 수 있습니다. 반대로 time.Duration처럼 API가 요구하는 타입을 고정해야 하면 typed constant를 씁니다. iota는 const 묶음 안에서 0부터 한 줄마다 증가하므로 bit flag나 연속 enum에 맞지만, 저장·네트워크에 노출되는 값은 숫자 순서가 바뀌지 않도록 별도 계약을 둡니다.
기본값
Go는 선언만 해도 기본값이 있다
var users []User
var cache map[string]User
var done chan struct{}slice, map, channel, pointer, interface의 zero value는 nil입니다. 다만 nil slice는 append가 가능하지만, nil map은 직접 쓰기 전에 make가 필요합니다.
var users []string
users = append(users, "a")
var counts map[string]int
// counts["a"] = 1 // panic
var done chan struct{}
// done <- struct{}{} // 영구히 block
// close(done) // panicnil map은 읽을 수 있지만 쓰면 panic이고, nil channel은 송수신이 완료되지 않은 채 기다립니다. "nil이면 비어 있다"가 아니라, 타입마다 어떤 연산이 가능한지로 구분해야 합니다.
선택 기준
| 상황 | 먼저 떠올릴 선택 |
|---|---|
| 함수 안에서 짧게 선언 | := |
| 타입을 명확히 보이고 싶음 | var name Type |
| zero value를 의도적으로 사용 | 초기값 없는 var |
| 바뀌지 않는 값 | const |
| 패키지 최상위 선언 | var 또는 const |
주의할 점
:=는 새 변수가 하나 이상 있을 때만 동작합니다. 기존 변수에 다시 값을 넣을 때는 =를 써야 합니다. 또한 zero value가 안전한 타입과 그렇지 않은 타입이 다르므로, map과 channel처럼 make가 필요한 값은 선언 직후 사용 가능 여부를 확인해야 합니다.
참고 링크
3 sources