
프로그래밍의 근간, 변수와 상수의 무게감
코드 에디터에 빨간 밑줄이 그어지는 순간을 마주하면 누구나 당혹감을 느껴요. 분명 어제까지 잘 작동하던 논리였는데, 왜 갑자기 타입이 맞지 않는다거나 선언되지 않았다는 에러가 뜨는 걸까요? 특히 Python이나 JavaScript처럼 유연한 언어를 먼저 접했다면, Go 언어의 엄격한 규칙은 마치 거대한 벽처럼 느껴질 수 있어요.
하지만 이 벽은 사실 여러분을 보호하기 위한 안전장치예요. Go는 컴파일 단계에서 최대한 많은 오류를 잡아내어, 프로그램이 실제 서비스 단계에서 예상치 못한 방식으로 작동하는 것을 방지하거든요. 그 중심에는 데이터를 담는 그릇인 변수와, 절대로 변하지 않는 약속인 상수가 있어요. 이 두 가지를 제대로 다루지 못하면 아무리 복잡한 알고리즘을 짜더라도 프로그램은 금세 모래성처럼 무너지고 말아요.
많은 입문자가 단순히 “값을 저장하는 것”이라고 가볍게 생각하지만, 실무에서는 이 데이터를 어떻게 관리하고 어떤 생명 주기를 갖게 할지가 시스템의 성능과 안정성을 결정해요. 메모리를 얼마나 효율적으로 쓸지, 값이 변하면 안 되는 지점에서 실수로 값을 바꿨을 때 어떤 대가를 치를지 고민하는 과정이 바로 프로그래밍의 본질이죠.
오늘 이 가이드를 통해 Go 변수 시작하기를 위한 모든 기초를 탄탄하게 다져보려고 해요. 단순히 문법을 외우는 것이 아니라, 왜 Go가 이런 방식을 선택했는지 그 철학을 이해하는 데 집중할 거예요.
- Go 변수와 상수의 근본적인 개념 차이
- 상황에 맞는 적절한 선언 방식 선택하기
- 데이터 타입과 제로 값(Zero Value)의 원리
- 실전 프로젝트에서 자주 발생하는 실수와 해결책
효율적인 코딩을 위한 사전 준비와 개념 정리
본격적으로 코드를 작성하기 전에, 우리가 사용할 도구와 기초 지식을 점검해야 해요. Go 언어는 매우 간결하지만, 그 간결함 속에 숨겨진 규칙들을 미리 알고 있어야 시행착오를 줄일 수 있어요. 준비물은 거창하지 않아요. 잘 설치된 Go 환경과 코드를 작성할 에디터만 있으면 충분해요.
환경 구축과 도구 선택
가장 먼저 Go Toolchain이 설치되어 있어야 해요. 터미널에서 go version 명령어를 입력했을 때 버전 정보가 정상적으로 출력된다면 준비는 끝난 셈이에요. 에디터는 Visual Studio Code(VS Code)를 강력하게 추천해요. Go 확장 프로그램을 설치하면 자동 완성은 물론, 선언되지 않은 변수를 즉시 찾아주는 강력한 기능을 사용할 수 있거든요.
핵심 용어와 판단 기준
변수를 다룰 때 가장 먼저 결정해야 하는 것은 “어떤 방식으로 선언할 것인가”예요. Go에는 크게 세 가지 방식이 있어요. 하나는 가장 명시적인 var 키워드, 다른 하나는 간결한 := 단축 선언, 마지막으로 변하지 않는 값을 보장하는 const예요. 이를 상황에 맞게 선택하는 기준을 아래 표로 정리해 보았어요.
| 선언 방식 | 주요 특징 | 권장 사용 상황 |
|---|---|---|
| var 키워드 | 타입을 명시적으로 지정 가능 | 전역 변수 선언 또는 타입이 중요할 때 |
| := (단축 선언) | 타입 추론을 통해 매우 간결함 | 함수 내부의 지역 변수 선언 시 |
| const 키워드 | 한 번 정하면 변경 불가 | 설정값, 수학적 상수 등 고정 데이터 |
위 표를 보면 알 수 있듯이, 모든 상황에서 하나의 방식만 고집하는 것은 좋지 않아요. 함수 내부에서는 가급적 단축 선언을 사용하되, 값이 변하지 않아야 하는 데이터는 반드시 상수로 분리하는 습관을 들이는 것이 Go다운 코드를 작성하는 첫걸음이에요.
Go는 선언만 하고 사용하지 않는 변수가 있으면 컴파일 에러를 발생시켜요. 이는 코드가 지저분해지는 것을 막고 메모리 낭비를 원천 차단하기 위한 Go만의 아주 매력적인 규칙이에요.
단계별 실행: 변수와 상수 완벽 마스터하기
이제 이론을 넘어 실제 코드로 구현해 볼 시간이에요. Go의 변수와 상수는 매우 엄격하면서도, 익숙해지면 놀라울 정도로 직관적이에요. 단계별로 차근차근 따라와 주세요.
STEP 1. 변수 선언의 두 가지 얼굴
Go에서 변수를 만드는 방법은 크게 두 가지로 나뉘어요. 첫 번째는 명시적 선언이고, 두 번째는 암시적 선언이에요.
명시적 선언은 var 키워드를 사용하는 방식이에요. var name string = "Go"와 같이 이름, 타입, 값을 모두 적어줄 수 있죠. 이 방식은 주로 함수의 밖(패키지 수준)에서 변수를 만들 때 사용해요. 전역 변수는 프로그램 어디서든 접근 가능해야 하므로, 타입을 명확히 밝혀주는 것이 가독성과 안정성 면에서 유리하기 때문이에요.
반면, 함수 내부에서 빠르게 변수를 만들 때는 := 기호를 사용해요. age := 25라고만 적어도 Go 컴파일러는 25가 숫자라는 것을 알아채고 자동으로 정수형(int)으로 지정해 줘요. 이를 타입 추론이라고 불러요. 코드가 훨씬 간결해지지만, 너무 남발하면 나중에 코드를 읽는 사람이 이 변수가 정확히 어떤 타입인지 헷갈릴 수 있으니 주의가 필요해요.
STEP 2. 데이터 타입과 제로 값의 마법
Go는 정적 타입 언어예요. 즉, 한 번 정해진 변수의 타입은 중간에 바꿀 수 없어요. 기본적으로 자주 쓰이는 타입은 다음과 같아요.
- 정수형: int, int64 (숫자 계산용)
- 실수형: float64 (소수점 계산용)
- 문자열: string (텍스트 데이터)
- 불리언: bool (true 또는 false)
여기서 꼭 기억해야 할 개념이 바로 제로 값(Zero Value)이에요. 다른 언어에서는 변수를 선언하고 값을 넣지 않으면 쓰레기 값이 들어있거나 에러가 나기도 하지만, Go는 친절하게도 미리 정해진 기본값을 넣어줘요. 정수는 0, 실수는 0.0, 문자열은 “”, 불리언은 false가 기본값이에요. 덕분에 초기화되지 않은 변수를 사용할 때 발생하는 런타임 에러를 획기적으로 줄일 수 있어요.
STEP 3. 변하지 않는 약속, 상수(const) 활용하기
프로그램을 만들다 보면 절대 바뀌면 안 되는 값들이 생겨요. 예를 들어 원주율(Pi)이나 서버의 포트 번호, API의 기본 URL 같은 것들이죠. 이런 값들은 const로 선언해야 해요. 상수는 선언과 동시에 반드시 값을 할당해야 하며, 한 번 할당된 값은 프로그램이 종료될 때까지 수정할 수 없어요.
상수는
:= 연산자를 사용하여 선언할 수 없어요. 반드시 const 키워드를 명시해야 한다는 점을 잊지 마세요.상수를 사용하면 코드를 읽는 동료 개발자에게 “이 값은 프로그램 실행 중에 절대 건드리지 마세요”라는 강력한 메시지를 전달할 수 있어 코드의 의도가 명확해져요.
STEP 4. 변수의 생명 주기와 스코프(Scope) 이해하기
변수가 어디까지 살아있고, 어디서 접근할 수 있는지를 결정하는 것이 바로 스코프예요. Go에서는 중괄호 {}를 기준으로 범위를 나누어요. 함수 안에서 선언된 변수는 그 함수가 끝나면 메모리에서 사라지는 지역 변수가 돼요. 반면, 함수 밖에서 선언된 변수는 패키지 전체에서 사용할 수 있는 전역 변수가 되죠.
여기서 초보자들이 가장 많이 빠지는 함정이 바로 변수 섀도잉(Shadowing)이에요. 상위 스코프에 있는 변수와 똑같은 이름의 변수를 하위 스코프에서 다시 선언하면, 하위 스코프에서는 원래의 변수가 아닌 새로 만든 변수만 보이게 돼요. 이는 논리적 오류를 일으키는 주범이므로, 변수 이름을 지을 때 신중해야 해요.
STEP 5. 실전 예제: 사용자 프로필 관리 시스템
이론을 종합하여 간단한 사용자 관리 시스템의 로직을 구성해 볼게요. 이 시나리오는 실제 서비스의 데이터를 다루는 느낌을 줄 거예요.
상황: 사용자의 이름은 고정된 식별자이고, 나이는 바뀔 수 있으며, 서비스의 버전은 절대 변하지 않습니다.
- 상수: 서비스 버전 (v1.0.0)
- 변수(고정): 사용자 ID (문자열)
- 변수(가변): 사용자 나이 (정수), 사용자 포인트 (실수)
이런 구조로 코드를 설계하면, 데이터의 성격에 따라 변수와 상수를 명확히 구분하여 시스템의 안정성을 높일 수 있어요. 실제 구현 시에는 각 데이터의 타입이 계산 과정에서 충돌하지 않도록(예: 정수와 실수의 연산 시 타입 변환) 주의를 기울여야 합니다.
자주 하는 실수와 해결법 및 FAQ
Go를 배우다 보면 누구나 비슷한 지점에서 막히곤 해요. 시행착오를 줄이기 위해 가장 흔한 실수들을 모아 정리했습니다.
자주 하는 실수와 해결법
❌ 실수: 상수를 선언한 후 값을 변경하려고 함
왜 발생하는가: 상수의 정의 자체가 “불변”이기 때문이에요.
✅ 해결법: 값이 변해야 하는 데이터라면 const 대신 var를 사용하세요.
❌ 실수: 함수 내부에서 var를 써야 할 곳에 :=를 남용함
왜 발생하는가: 코드의 간결함만 추구하다 보니 타입의 명확성이 떨어지기 때문이에요.
✅ 해결법: 복잡한 타입이나 의도가 중요한 변수는 var로 타입을 명시해 주세요.
❌ 실수: 선언만 하고 사용하지 않는 변수를 방치함
왜 발생하는가: Go의 엄격한 컴파일러 규칙을 간과했기 때문이에요.
✅ 해결법: 변수를 선언했다면 반드시 로직 내에서 사용하거나, 테스트 중이라면 잠시 삭제하세요.
❌ 실수: 전역 범위에서 :=를 사용하여 변수 선언
왜 발생하는가: 단축 선언은 함수 내부에서만 허용되는 문법이기 때문이에요.
✅ 해결법: 패키지 수준의 변수는 반드시 var 키워드를 사용하세요.
❌ 실수: 서로 다른 타입 간의 연산을 시도함 (예: int + float64)
왜 발생하는가: Go는 자동 형 변환(Implicit Conversion)을 허용하지 않기 때문이에요.
✅ 해결법: float64(myInt) + myFloat와 같이 명시적으로 타입을 변환하세요.
자주 묻는 질문
Q. var와 :=의 차이가 정확히 무엇인가요?
var는 타입과 초기값을 명시적으로 제어하고 싶을 때, 특히 함수 밖에서 쓸 때 사용해요. 반면 :=는 함수 안에서 타입을 컴파일러에게 맡기고 빠르게 선언하고 싶을 때 쓰는 편의 기능이에요.
Q. 상수는 왜 반드시 선언과 동시에 값을 넣어야 하나요?
상수는 한 번 정해지면 바꿀 수 없는 “약속”이기 때문이에요. 나중에 값을 넣으려고 시도하는 것 자체가 상수의 의미를 부정하는 것이라 컴파일러가 이를 허용하지 않아요.
Q. Go에서 변수를 선언만 하고 안 쓰면 왜 에러가 나나요?
이는 의도적인 설계예요. 사용하지 않는 변수는 메모리를 점유하면서도 아무런 역할을 하지 않기 때문에, 코드를 깨끗하게 유지하고 잠재적인 버그를 방지하기 위해 컴파일러가 엄격하게 관리하는 것이랍니다.
Q. 데이터 타입을 자동으로 지정해도 괜찮을까요?
대부분의 경우 :=를 통한 타입 추론은 안전하고 효율적이에요. 하지만 데이터의 크기(예: 매우 큰 숫자)나 정밀도가 중요한 경우에는 직접 타입을 지정해 주는 것이 더 안전해요.
Q. 상수에 함수 호출 결과를 넣을 수 있나요?
아니요, 상수는 컴파일 시간에 결정되는 상수 값(숫자, 문자열 등)만 가질 수 있어요. 함수 호출 결과처럼 실행 중에 결정되는 값은 반드시 변수로 선언해야 합니다.
지속 가능한 코딩을 위한 마무리
변수와 상수를 이해하는 것은 단순히 문법 하나를 익히는 것을 넘어, Go라는 언어가 데이터를 대하는 태도를 배우는 과정이에요. 데이터의 성격에 맞는 그릇을 선택하고, 그 그릇이 어디까지 살아있는지를 파악하는 것만으로도 여러분의 코드는 훨씬 견고해질 거예요.
- 상황에 따라
var(명시적)와:=(간결함)를 구분해서 사용하세요. - 변하지 않는 값은 반드시
const로 선언하여 안전을 확보하세요. - Go의 제로 값(Zero Value) 개념을 숙지하여 초기화 오류를 방지하세요.
- 사용하지 않는 변수는 컴파일 에러를 유발하므로 즉시 정리하세요.
- 타입 간 연산 시에는 반드시 명시적 형 변환을 수행하세요.
- 변수 섀도잉을 피하기 위해 이름을 명확하고 고유하게 지으세요.
오늘 배운 내용을 바탕으로 직접 작은 프로그램을 만들어 보는 것이 가장 중요해요. 눈으로 읽는 것과 손으로 치는 것은 천지차이니까요.
다음 단계로 나아가기
- 오늘 할 일: 로컬 환경에 Go를 설치하고
Hello, World!를 출력해 보세요. - 이번 주 할 일: 다양한 데이터 타입을 사용하여 간단한 계산기 프로그램을 만들어 보세요.
- 실행 직전 할 일: 변수 선언 방식(var vs :=)을 섞어 쓰며 어떤 에러가 발생하는지 직접 확인해 보세요.
Go 프로그래밍의 여정은 이제 시작이에요. 공부하시다가 막히는 부분이 있거나 이해가 안 되는 코드가 있다면 언제든 댓글로 질문을 남겨 주세요. 함께 고민하고 답변해 드릴게요!
더 깊이 있는 Go 언어 학습을 원하신다면 Go 변수와 상수 완전 정복 가이드 글도 함께 읽어 보시는 것을 추천합니다.