고 기초 #1 시작과 첫 프로그램
이 시리즈는 Go(고 언어)를 처음 배우는 분, 또는 다른 언어를 알고 Go로 넘어오는 분을 위한 7편짜리 입문 강좌입니다.
- #1 시작과 첫 프로그램 ← 이번 글
- #2 변수, 타입, 상수
- #3 제어 흐름 — if/for/switch
- #4 함수, 다중 반환, error 타입
- #5 컬렉션 — array/slice/map
- #6 구조체와 메서드
- #7 패키지와 모듈 (go mod)
이번 글은 — 왜 Go를 쓰는지부터 정리하고, 셋업해서 첫 프로그램을 컴파일,실행하는 곳까지 갑니다.
Go가 무엇인가? #
**Go (또는 Golang)**는 2009년 Google이 발표한 컴파일 언어입니다. 디자인 목표가 명확합니다.
- 간결한 문법 — 키워드가 25개뿐, 학습 곡선이 가파르지 않음
- 빠른 컴파일과 실행 — 정적 컴파일, 단일 바이너리 결과
- 고루틴(goroutine) — 가벼운 동시성 모델
- 표준 라이브러리 — HTTP 서버, JSON, 암호화 등이 처음부터 풍부
CLI 도구, 백엔드 서버, 분산 시스템에서 특히 강합니다. Docker, Kubernetes, Terraform 같은 인프라 도구가 모두 Go로 작성됐습니다.
누구에게 잘 맞나? #
다음 중 하나라도 해당하면 Go가 잘 어울립니다.
- CLI 도구를 만들고 싶다 — 단일 바이너리로 배포하기 쉬움
- HTTP 서버 / API — 표준 라이브러리만으로 견고한 서버
- 동시성이 중요한 시스템 — 고루틴이 가장 단순한 답
- 자바스크립트/파이썬에서 더 빠른 언어로 가고 싶다 — 학습 곡선이 부드러움
C/C++ 만큼의 저수준 제어는 못 하지만, 시스템 프로그래밍과 응용 프로그래밍 사이의 좋은 접점 입니다.
다른 언어와 비교 #
대략적인 위치 감각을 잡아두면 좋습니다.
| Go | Python | JavaScript | Rust | |
|---|---|---|---|---|
| 타입 | 정적, 추론 | 동적 | 동적 (TS는 정적) | 정적, 강력 |
| 실행 | 컴파일 | 인터프리터 | JIT | 컴파일 |
| 학습 곡선 | 부드러움 | 가장 부드러움 | 부드러움 | 가파름 |
| 메모리 관리 | GC | GC | GC | 소유권/borrow checker |
| 동시성 | 고루틴 | asyncio/threading | 이벤트 루프 | async + 스레드 |
Go는 간결함과 성능 사이의 실용적인 위치를 차지합니다.
Go 설치하기 #
macOS #
brew install goLinux #
# Ubuntu/Debian
sudo apt install golang-go
# 또는 공식 사이트에서 tarball 받기
# https://go.dev/dl/Windows #
go.dev/dl에서 MSI 인스톨러 다운로드. 또는 winget install GoLang.Go.
설치 확인 #
go version
# go version go1.22.0 darwin/arm64처럼 출력이 시리즈는 Go 1.22 이상을 가정합니다. ServeMux 패턴 매칭, generics 등 최신 기능을 활용합니다.
첫 프로그램 — Hello World #
작업 폴더를 만들고:
mkdir hello-go
cd hello-go
go mod init hellogo mod init이 새 모듈을 시작합니다. go.mod 파일이 생성됩니다. 이건 #7 패키지와 모듈에서 자세히 다룹니다.
main.go 파일을 만들어 다음을 적습니다.
package main
import "fmt"
func main() {
fmt.Println("안녕, Go!")
}실행:
go run main.go
# 안녕, Go!go run은 컴파일과 실행을 한 번에 합니다. 컴파일된 바이너리를 따로 만들고 싶으면:
go build
./hello
# 안녕, Go!go build는 모듈 이름과 같은 이름의 바이너리(hello)를 만듭니다. Go의 가장 큰 장점 중 하나가 이것입니다 — 의존성이 모두 정적으로 묶인 단일 실행 파일.
코드 한 줄씩 풀어보기 #
package main
import "fmt"
func main() {
fmt.Println("안녕, Go!")
}package main— 이 파일은main패키지에 속합니다. 실행 가능한 프로그램은 항상 main 패키지의 main 함수에서 시작합니다.import "fmt"— 표준 라이브러리의fmt패키지를 가져옵니다. fmt는 입출력 포맷팅용입니다.func main()— 프로그램의 진입점. 매개변수도, 반환값도 없는 함수.fmt.Println(...)— fmt 패키지의 Println 함수를 호출. 외부에 노출된 이름은 항상 대문자로 시작합니다 (Go의 규칙).
Go의 가장 두드러진 문법 — 세미콜론, 중괄호 #
1) 세미콜론 없음 #
fmt.Println("a")
fmt.Println("b")줄 끝의 세미콜론을 안 씁니다. 컴파일러가 자동으로 처리합니다. 다만 다음에 주의 — 여는 중괄호는 반드시 같은 줄에 와야 합니다.
// OK
func main() {
fmt.Println("hi")
}
// ✗ 컴파일 에러
func main()
{
fmt.Println("hi")
}2) 들여쓰기는 탭 #
Go는 표준 도구 gofmt가 코드를 자동 포맷팅합니다. 들여쓰기는 탭, 정렬은 정해진 규칙. 이 시리즈도 gofmt 결과 그대로 적습니다.
3) 자동 포맷팅 — go fmt
#
go fmt ./...저장 시 자동으로 포맷되도록 에디터에 설정해 두세요. VS Code의 Go 확장이 자동으로 처리해 줍니다.
변수 한 번 빠르게 — 미리보기 #
다음 글에서 자세히 다루지만, 분위기만 먼저 봅니다.
package main
import "fmt"
func main() {
name := "커티스"
age := 30
fmt.Printf("이름: %s, 나이: %d\n", name, age)
}:=가 선언과 할당을 한 번에 하는 단축 문법입니다. 타입은 우변에서 추론됩니다(여기선 string, int).
컴파일 단계에서 잡히는 사고들 #
Go가 처음 보는 사람들에게 의외인 부분입니다.
1) 사용하지 않는 변수는 컴파일 에러 #
func main() {
x := 10 // ✗ x declared but not used
fmt.Println("hi")
}다른 언어는 경고 정도지만, Go는 컴파일 자체를 막습니다. 코드 정리를 강제하는 디자인입니다.
2) 사용하지 않는 import도 에러 #
import (
"fmt"
"strings" // ✗ "strings" imported and not used
)
func main() {
fmt.Println("hi")
}같은 이유로. **gofmt와 goimports**가 자동으로 정리해 주니, 에디터 설정만 잘 두면 거의 만나지 않습니다.
3) 변수 그림자 (shadow) — 컴파일은 통과 #
x := 10
if true {
x := 20 // 새 x — 바깥의 x를 가리지만 통과
fmt.Println(x) // 20
}
fmt.Println(x) // 10이건 컴파일 에러는 아니지만 종종 버그의 원인입니다. 도구(go vet)가 일부 케이스를 잡아 줍니다.
표준 도구 — go 명령
#
자주 쓰는 서브 명령들.
go run main.go # 실행
go build # 빌드
go test ./... # 테스트 (전체 패키지)
go fmt ./... # 포맷
go vet ./... # 정적 분석 (의심스러운 패턴 검사)
go mod tidy # 의존성 정리
go mod init <이름> # 새 모듈 시작
go get <패키지> # 의존성 추가./...은 “현재 디렉토리와 모든 하위” 를 의미합니다.
에디터 — VS Code + Go 확장 #
VS Code에 Go 확장을 설치하면 자동완성, 점프, 포맷팅, 린팅이 모두 동작합니다. 처음 열면 추가 도구 설치 안내가 뜨니 모두 설치해 두세요.
JetBrains의 GoLand도 인기지만, VS Code만으로 거의 충분합니다.
Go Playground — 셋업 없이 시도 #
go.dev/play는 브라우저에서 바로 Go를 실행할 수 있는 공식 도구입니다. 작은 예제를 시험할 때, 또는 코드를 공유할 때 유용합니다.
마무리 #
이번 글에서 정리한 내용:
- Go는 간결한 문법 + 정적 컴파일 + 동시성에 강한 언어
- CLI, HTTP 서버, 분산 시스템에 특히 어울림
- 설치 확인은
go version. 시리즈는 1.22+ 가정 - 새 프로젝트는
go mod init으로 시작 go run main.go또는go buildpackage main+func main()가 진입점- 외부 노출 이름은 대문자 시작 — Go의 가시성 규칙
- 사용하지 않는 변수/import는 컴파일 에러
gofmt/go vet등 표준 도구가 풍부
다음 글(#2 변수, 타입, 상수)에서는 Go의 기본 타입들과 변수 선언 방식들, 상수와 iota 패턴까지 정리합니다.