
Go 프로그래밍의 시작, 왜 변수 선언에서 막힐까요?
Go 언어를 처음 설치하고 첫 코드를 작성할 때, 가장 먼저 마주하는 벽은 생각보다 높아요. 분명히 값을 넣었는데 undefined variable라는 에러가 뜨거나, 분명히 숫자를 넣었는데 타입을 맞추지 않았다고 컴파일이 거부되는 경험을 자주 하게 되거든요. 다른 언어에서는 대충 넘어가던 부분들이 Go에서는 아주 엄격하게 작동하기 때문이에요.
이런 현상은 결코 여러분의 실력이 부족해서가 아니에요. Go 설계 철학 자체가 명확성과 안전성을 최우선으로 하기 때문에 발생하는 자연스러운 과정이에요. 변수를 어떻게 선언해야 하는지, 상수는 언제 써야 하는지, 그리고 왜 내가 쓴 코드가 에러를 뱉는지 이해하지 못하면 Go 학습은 계속해서 고통스러운 시간이 될 수밖에 없어요.
지금 이 글을 읽고 있는 분들은 아마도 변수 선언 규칙이 헷갈리거나, 컴파일 에러를 어떻게 해결해야 할지 몰라 답답함을 느끼고 계실 거예요. 이 글을 끝까지 읽고 나면, Go의 엄격한 규칙이 왜 우리를 도와주는 안전장치인지 깨닫게 될 거예요. 더불어 실전에서 바로 쓸 수 있는 효율적인 변수 관리 방법까지 확실히 내 것으로 만들 수 있어요.
- Go 변수 선언의 다양한 방식과 차이점
- 상수를 사용하는 올바른 타이밍과 규칙
- 초보자가 가장 많이 하는 실수 7가지와 해결책
- 실무에서 유용한 Go 변수 관련 FAQ
본격적인 시작 전, 꼭 알아야 할 기초 지식
변수와 상수를 다루기 전에 먼저 머릿속에 정리해두어야 할 개념이 있어요. Go는 정적 타입 언어예요. 즉, 프로그램이 실행되기 전에 모든 변수의 타입이 결정되어야 한다는 뜻이에요. 이 규칙을 이해하지 못하면 코드를 작성할 때마다 타입 불일치 에러로 고생하게 돼요.
또한, Go는 사용하지 않는 변수를 허용하지 않아요. 다른 언어에서는 선언만 해두고 나중에 써도 되지만, Go 컴파일러는 사용하지 않는 변수가 있다면 즉시 컴파일 에러를 발생시켜요. 이는 메모리 낭비를 막고 코드를 깨끗하게 유지하기 위한 Go만의 아주 강력한 규칙이에요.
아래 표를 통해 가장 기본이 되는 선언 방식의 차이를 먼저 확인해 보세요. 어떤 상황에서 무엇을 써야 할지 판단하는 기준이 될 거예요.
| 구분 | var 선언 | 단축 선언 (:=) | 상수 (const) |
|---|---|---|---|
| 값 변경 가능 여부 | 가능함 | 가능함 | 불가능함 |
| 타입 명시 여부 | 명시 또는 생략 가능 | 자동 추론 | 자동 추론 또는 명시 |
| 사용 권장 위치 | 패키지 레벨/함수 내부 | 함수 내부만 가능 | 패키지 레벨/함수 내부 |
| 주요 용도 | 전역 변수 또는 명시적 타입 필요 시 | 지역 변수의 빠른 선언 | 변경되면 안 되는 고정값 |
이 표를 기억하면 코드를 짤 때 고민하는 시간이 훨씬 줄어들 거예요. 특히 단축 선언은 함수 내부에서만 쓸 수 있다는 점을 절대 잊지 마세요. 패키지 레벨(함수 밖)에서 이 연산자를 쓰려고 하면 바로 에러가 발생해요.
실전 Go 변수와 상수 마스터하기
이제 본격적으로 단계별 실습을 통해 Go의 변수와 상수를 완벽히 다뤄볼게요. 단순히 문법을 외우는 것이 아니라, 왜 이 방식을 써야 하는지에 집중하며 따라와 주세요.
STEP 1. 가장 기본이 되는 var 선언법 이해하기
가장 정석적인 방법은 var 키워드를 사용하는 것이에요. 이 방법은 변수의 타입(Type)을 명확하게 드러내고 싶을 때 아주 유용해요. 예를 들어, 정수형 데이터를 담을 것인지, 실수형 데이터를 담을 것인지 컴파일러에게 정확히 알려주는 거죠.
var age int = 25와 같이 작성하면, age라는 이름의 변수가 정수(int) 타입임을 확실히 선언하게 돼요. 만약 타입을 생략하고 var age = 25라고만 적어도 Go는 똑똑하게 25가 정수라는 것을 알아차려요. 하지만 실무에서는 코드를 읽는 동료들을 위해 타입을 명시적으로 적어주는 것이 훨씬 좋은 습관이에요. 특히 함수의 파라미터나 리턴 값과 관련된 변수에서는 타입 명시가 가독성을 크게 높여줘요.
STEP 2. 효율적인 단축 선언 (:=) 활용하기
Go 프로그래머들이 가장 사랑하는 문법은 바로 := 연산자예요. 이 방식은 var 키워드와 타입 명시를 한꺼번에 생략할 수 있게 해주거든요. 코드가 훨씬 간결해지고 읽기 편해지는 장점이 있어요.
예를 들어, name := "Go"라고 쓰면 한 줄로 변수 선언과 값 할당이 끝나요. 하지만 여기서 주의할 점이 있어요. 단축 선언은 반드시 함수 내부(Local Scope)에서만 사용 가능해요. 함수 밖에서 패키지 수준의 변수를 선언할 때는 반드시 var를 사용해야 해요. 또한, 단축 선언은 기존에 선언된 변수에 새로운 값을 넣는 용도가 아니라, 새로운 변수를 만드는 용도라는 점을 명심해야 해요.
STEP 3. 변하지 않는 값, 상수의 정의와 사용
프로그램을 만들다 보면 프로그램이 끝날 때까지 절대로 변해서는 안 되는 값들이 있어요. 예를 들어 원주율(Pi)이나 서버의 포트 번호, 혹은 API의 버전 정보 같은 것들이죠. 이런 값들을 변수로 만들면 실수로 값을 바꿨을 때 찾기 힘든 버그가 생길 수 있어요. 이때 사용하는 것이 바로 const 키워드예요.
const Pi = 3.14159와 같이 선언된 상수는 이후에 값을 변경하려고 하면 컴파일 단계에서 즉시 차단돼요. 상수는 실행 중에 값이 계산되는 것이 아니라, 컴파일할 때 이미 값이 결정되어야 한다는 특징이 있어요. 따라서 함수 호출 결과나 사용자 입력값처럼 런타임(Runtime)에 결정되는 값은 상수로 만들 수 없어요.
STEP 4. 여러 개의 변수와 상수를 한 번에 관리하기
변수나 상수가 많아지면 코드가 지저분해질 수 있어요. Go는 이를 깔끔하게 정리할 수 있는 묶음 선언 기능을 제공해요. var나 const를 한 번만 쓰고 괄호 ()를 사용해 여러 항목을 나열하는 방식이에요.
var (와 같이 작성하면 관련 있는 변수들을 논리적으로 묶을 수 있어요. 상수의 경우에도
userCount int = 10
isReady bool = true
)const (처럼 정의하면 코드의 구조가 훨씬 명확해져요. 이렇게 묶어서 선언하면 코드가 훨씬 전문적으로 보이고, 관련 데이터들을 한눈에 파악하기 쉬워져요.
StatusOk = 200
StatusNotFound = 404
)
STEP 5. Go의 독특한 특징: 제로 값(Zero Value)
Go를 배우면서 가장 놀라운 점 중 하나는 변수를 선언만 하고 값을 넣지 않아도 에러가 나지 않는다는 거예요. 모든 타입에는 값이 할당되지 않았을 때 들어가는 기본값(Zero Value)이 정해져 있기 때문이에요.
예를 들어, int 타입 변수는 0, float64는 0.0, bool은 false, 그리고 string은 빈 문자열 ""이 기본값으로 할당돼요. 이는 다른 언어에서 흔히 발생하는 undefined 또는 null로 인한 예상치 못한 오류를 방지하는 아주 훌륭한 설계예요. 덕분에 개발자는 변수가 초기화되지 않았을까 봐 걱정하는 대신, 비즈니스 로직에 더 집중할 수 있어요.
서버 설정을 구성할 때, 서버 포트와 타임아웃 값은
const로 고정하고, 현재 접속자 수나 로그 메시지는 var를 사용하여 동적으로 관리하는 것이 가장 표준적인 패턴이에요.자주 하는 실수와 해결법
Go를 처음 다루는 분들이 가장 흔히 겪는 실수들을 정리했어요. 에러 메시지를 읽는 법을 배우면 해결 속도가 훨씬 빨라질 거예요.
- ❌ 사용하지 않는 변수 선언 → unused variable x [declared but not used] 에러 발생 → ✅ 사용하지 않을 변수는 과감히 삭제하거나, 테스트 중이라면
_ = x를 사용하여 컴파일러를 안심시켜 주세요. - ❌ 상수에 새로운 값 할당 → cannot assign to x 에러 발생 → ✅ 상수는 값을 바꿀 수 없어요. 값을 변경해야 한다면
var로 선언을 변경해야 해요. - ❌ 함수 밖에서 단축 선언 사용 → syntax error: unexpected := 에러 발생 → ✅ 패키지 레벨에서는 반드시
var키워드를 사용해야 해요. - ❌ 타입 불일치 연산 → mismatched types int and float64 에러 발생 → ✅ Go는 자동 형변환을 해주지 않아요.
float64(myInt)와 같이 명시적으로 타입을 변환해 주세요. - ❌ 변수 이름 중복 선언 → no new variables on left side of := 에러 발생 → ✅
:=는 새로운 변수를 만들 때만 써요. 이미 있는 변수에 값을 넣을 때는=를 사용하세요.
자주 묻는 질문
Q. 변수와 상수의 차이를 한 문장으로 요약해 주실 수 있나요?
A. 변수는 프로그램 실행 중에 값이 변할 수 있는 저장 공간이고, 상수는 한 번 정해지면 절대 변하지 않는 고정된 값이에요.
Q. := 연산자를 쓰면 타입 지정이 아예 필요 없나요?
A. 네, Go의 타입 추론(Type Inference) 기능 덕분에 할당되는 값에 따라 타입이 자동으로 결정돼요. 하지만 코드가 복잡해지면 명시적으로 타입을 적는 것이 가독성에 더 좋을 때가 많아요.
Q. Go에는 왜 null 값이 없나요?
A. Go는 nil이라는 개념이 있지만, 모든 타입에 존재하는 것은 아니에요. 대신 각 타입의 제로 값(Zero Value)을 활용하여 더 안전한 프로그래밍을 유도하도록 설계되었어요.
Q. 상수를 만들 때 꼭 타입을 써야 하나요?
A. 아니요, 상수는 타입을 생략해도 되는데 이를 untyped constant라고 불러요. 이렇게 하면 나중에 다양한 타입의 변수에 더 유연하게 할당할 수 있어 편리해요.
Q. 전역 변수를 많이 써도 괜찮을까요?
A. 가급적 피하는 것이 좋아요. 전역 변수는 어디서든 접근 가능하기 때문에 프로그램의 흐름을 추적하기 어렵게 만들고, 예측 불가능한 버그를 일으킬 확률이 높거든요.
핵심 요약과 다음 단계
오늘 배운 내용을 다시 한번 정리해 드릴게요. 이 내용만 기억해도 Go의 기초 변수 관리는 마스터한 것이나 다름없어요.
var는 패키지/함수 모두 사용 가능하며 명시적 타입 지정에 유리해요.:=는 함수 내부에서만 사용 가능한 아주 편리한 단축 선언 방식이에요.const는 변경이 불가능한 값을 정의할 때 사용하며 컴파일 시점에 결정돼요.- 사용하지 않는 변수는 Go에서 엄격히 금지되니 주의하세요.
- 모든 타입에는 기본값인 제로 값(Zero Value)이 존재하여 안전성을 높여줘요.
- 타입이 다르면 자동 형변환이 안 되므로 명시적 변환이 필요해요.
이제 여러분은 Go의 변수와 상수를 다룰 준비가 완벽하게 끝났어요! 단순히 문법을 아는 것을 넘어, 왜 이런 규칙이 있는지 이해했다는 점이 정말 중요해요.
오늘 바로 해보실 일: 지금 바로 IDE를 켜고, var와 :=를 섞어서 사용해 보며 컴파일러가 어떻게 반응하는지 직접 확인해 보세요. 직접 에러를 마주해 보는 것이 가장 빠른 학습법이에요.
다음 단계 예고: 변수를 다루는 법을 익혔다면, 이제 이 변수들을 어떻게 효율적으로 묶고 전달할지 고민해야 할 때예요. 다음 편에서는 Go의 데이터 구조와 슬라이스(Slice) 활용법을 아주 깊이 있게 다룰 예정이에요. 놓치지 않으려면 구독 버튼을 꼭 눌러주세요!
관련된 기초 개념이 더 궁금하시다면 Go 변수와 상수 완전 가이드 글을 함께 읽어보시는 것을 추천드려요.