Menu

Golang이란? Go 언어의 특징과 용도를 예제로 설명

Go(흔히 Golang이라고 부름)는 빠르고 안정적인 서버와 도구를 만들기 위해 Google에서 설계한 정적 타입 컴파일 언어입니다. Go 언어가 무엇인지, 어디에 쓰는지, 어디에서 부족한지를 다룹니다.

이 페이지에는 실행 가능한 에디터가 있습니다 - 편집하고 실행하면 결과를 바로 볼 수 있습니다.

Go는 Google에서 만든 정적 타입 컴파일 프로그래밍 언어입니다. 네이티브 바이너리 하나를 만들고, 몇 초 만에 컴파일되며, 가비지 컬렉션이 있고, 고루틴과 채널을 통해 동시성이 언어에 내장되어 있습니다. 주 무대는 서버 쪽 소프트웨어입니다. API, 네트워크 서비스, 그리고 그것들을 운영하는 명령줄 도구와 클라우드 도구입니다.

완전한 Go 프로그램입니다. Run을 눌러 보세요.

모든 Go 프로그램은 package mainfunc main()에서 시작합니다. :=는 변수를 선언하고 타입을 추론합니다(여기서는 문자열 슬라이스인 []string). range는 슬라이스를 훑으면서 인덱스와 값을 줍니다. fmtstrings는 표준 라이브러리에서 오며, 표준 라이브러리가 충분히 커서 다른 것을 전혀 import하지 않는 프로그램도 많습니다.

Go와 Golang: 이름 이야기

언어의 이름은 Go입니다. "Golang"은 프로젝트의 첫 웹사이트인 golang.org에서 온 별명입니다(사이트는 지금 go.dev에 있습니다). 웹에서 "go"를 검색하면 이 언어만 빼고 모든 것이 나오기 때문에 사람들이 계속 이 이름을 썼습니다. 공식 문서는 "Go"라고 하지만 거의 모든 사람이 검색창에 "golang"이라고 입력하며, 둘은 같은 것을 뜻합니다. 국내에서는 "고랭"이나 "Go 언어"라고도 부릅니다. 별도의 "Golang" 제품이나 방언은 없습니다.

누가, 왜 Go를 만들었나

Robert Griesemer, Rob Pike, Ken Thompson이 2007년 Google에서 Go를 설계하기 시작했습니다. 2009년 11월 오픈 소스로 공개되었고, Go 1.0은 2012년 3월에 나왔습니다.

동기는 현실적이었습니다. Google의 거대한 C++와 Java 코드베이스는 빌드가 오래 걸렸고, 의존성 그래프는 관리하기 어려웠으며, 멀티코어 머신과 네트워크 서비스가 일상이 되었는데도 동시성 코드를 작성하다 보면 실수하기 쉬웠습니다. Go의 설계는 이 문제들에 직접 답합니다:

  • 빠른 빌드. import가 명시적이고, 사용하지 않는 import는 컴파일 오류이며, 컴파일러가 헤더를 다시 파싱하지 않으므로 큰 프로그램도 몇 초 만에 빌드됩니다.
  • 단순한 언어. 키워드가 적고, 반복문은 하나(for)이며, 상속도 예외도 없습니다. 다른 사람이 쓴 코드가 비슷한 모습이 되는 경향이 있어서 큰 팀에서 리뷰하기 좋습니다.
  • 언어 기능으로서의 동시성. 동시 작업을 시작하는 데는 키워드 하나 go면 되고, 채널로 작업끼리 통신합니다.
  • 쉬운 배포. 결과물은 서버에 복사하면 되는 바이너리 하나입니다. 보통 정적으로 링크되며, cgo가 켜져 있으면 net 같은 패키지가 시스템 C 라이브러리에 링크될 수 있고 CGO_ENABLED=0으로 이를 끌 수 있습니다.

Go 1.0에는 Go 1 호환성 약속도 함께 나왔습니다. Go 1.0용으로 작성한 프로그램은 이후의 1.x 릴리스에서도 계속 컴파일되고 실행된다는 약속입니다. 실제로 툴체인을 업그레이드해도 코드가 깨지는 일이 드물며, 팀들이 오래 운영하는 서비스에 Go를 믿고 쓰는 큰 이유입니다.

Golang은 어디에 쓰이나

Go는 프로그램이 네트워크와 통신하고, 오래 실행되고, 배포하기 쉬워야 하는 곳에서 가장 강합니다:

분야예시
웹 API와 마이크로서비스HTTP와 gRPC 서비스, 웹과 모바일 앱의 백엔드
클라우드와 인프라 도구Docker, Kubernetes, Terraform, Prometheus
명령줄 도구플랫폼마다 바이너리 하나로 배포되는 개발자 CLI
네트워킹프록시, 로드 밸런서, DNS 서버
데이터 파이프라인큐를 읽고, 레코드를 변환하고, 데이터베이스에 쓰는 워커

GUI 데스크톱 앱, 모바일 앱, 브라우저 프런트엔드, 수치 계산이나 머신러닝 작업에는 덜 어울립니다. 그런 분야에서는 다른 생태계의 라이브러리가 훨씬 좋습니다.

주요 특징과 코드

타입 추론이 있는 정적 타입

모든 변수는 컴파일 타임에 고정되는 타입을 갖지만, 직접 적을 일은 드뭅니다. :=가 추론합니다:

Go는 숫자 타입 사이를 절대 조용히 변환하지 않습니다. 하나는 int이고 다른 하나는 float64이므로 count * price는 컴파일되지 않고, float64(count)를 직접 써야 합니다. 이 덕분에 조용한 절삭이나 정밀도 버그가 생기지 않습니다.

오류는 값이다

Go에는 예외가 없습니다. 실패할 수 있는 함수는 마지막 결과로 error를 반환하고, 호출자가 그것을 확인합니다:

if err != nil 패턴은 Go 코드에서 가장 눈에 띄는 줄입니다. 장황하지만 그게 핵심입니다. 프로그램이 실패할 수 있는 모든 지점이 발생한 자리에서 보입니다. 오류를 감싸고 살펴보는 방법은 오류 처리를 참고하세요.

고루틴과 채널

고루틴은 프로그램의 나머지 부분과 동시에 실행되는 함수입니다. 스택이 몇 킬로바이트밖에 들지 않아서 수천 개를 실행하는 것도 평범한 일입니다. 채널은 고루틴 사이에 값을 안전하게 전달합니다:

세 고루틴이 동시에 실행되므로 세 줄은 어떤 순서로든 출력될 수 있습니다. 몇 번 실행해 보면 다른 순서를 볼 수도 있습니다. main은 정확히 값 세 개를 받으므로 종료하기 전에 모두를 기다립니다.

"implements" 없는 인터페이스

타입은 알맞은 메서드를 갖는 것만으로 인터페이스를 만족합니다. implements 키워드는 없습니다:

RectCircleShape를 전혀 언급하지 않지만 둘 다 []Shape에 저장할 수 있습니다. 덕분에 구체 타입이 작성되고 한참 뒤에, 그것을 사용하는 패키지에서 인터페이스를 정의할 수 있습니다.

하나의 툴체인

go 명령이 모든 일을 합니다. go run은 컴파일하고 실행하며, go build는 바이너리를 만들고, go test는 테스트를 실행하고, go fmt는 코드를 포매팅하고, go vet은 의심스러운 구문을 잡고, go mod는 의존성을 관리합니다. 공식 포매팅 스타일이 하나뿐이고 gofmt가 강제하므로 Go 프로젝트에서는 중괄호나 들여쓰기로 논쟁하지 않습니다.

Go가 일부러 뺀 것

다른 언어에서 흔한 몇몇 기능은 의도적으로 빠져 있습니다:

  • 클래스와 상속이 없습니다. 구조체, 메서드, 인터페이스, 임베딩을 씁니다.
  • 예외가 없습니다. 오류는 반환되는 값입니다. panic은 있지만 일반적인 실패가 아니라 버그를 위한 것입니다.
  • 삼항 연산자가 없습니다. if/else를 씁니다.
  • while 키워드가 없습니다. for가 모든 반복을 다룹니다.
  • 함수 오버로딩과 기본 인자가 없습니다.
  • 제네릭은 Go 1.18부터만 있으며, C++ 템플릿이나 Java 제네릭에 비해 일부러 제한적입니다.

솔직한 단점

장황함. 명시적인 오류 검사와 삼항 연산자 같은 지름길이 없다는 점 때문에 Go 코드는 같은 일을 하는 Python이나 Kotlin 코드보다 깁니다. 읽기는 쉽지만 쓰는 데는 줄이 더 듭니다.

가비지 컬렉션. Go의 컬렉터는 일시 정지 시간이 짧지만 그래도 가비지 컬렉터입니다. 경성 실시간 시스템이나 할당 하나하나가 중요한 코드라면 C, C++, Rust가 더 많은 통제권을 줍니다.

nil 값. Go에는 nil 포인터, 맵, 슬라이스, 인터페이스가 있습니다. nil 포인터 역참조는 런타임 패닉이며, 컴파일러는 Rust의 타입 시스템처럼 이를 막아 주지 않습니다.

작은 타입 시스템. 합 타입이 없고, 열거형도 없으며(상수와 iota로 만듭니다), 제네릭은 흔한 경우는 다루지만 고급 타입 수준 프로그래밍은 다루지 못합니다.

생태계의 빈틈. 웹 서비스, 데이터베이스, 클라우드 API용 라이브러리는 훌륭합니다. GUI, 과학 계산, 머신러닝이라면 Python, C++, Julia 쪽이 훨씬 많습니다.

다른 언어와 비교한 Go

GoPythonJavaRust
타입정적동적정적정적
실행 방식네이티브 바이너리인터프리터JVM 바이트코드네이티브 바이너리
메모리가비지 컬렉션가비지 컬렉션가비지 컬렉션소유권, GC 없음
동시성고루틴, 채널스레드, asyncio(GIL이 CPU 병렬성을 제한)스레드, 가상 스레드스레드, async
학습 곡선낮음낮음중간높음

Rust의 학습 곡선이나 Java의 격식 없이 컴파일 언어의 성능과 단순한 배포를 원할 때 Go를 고르세요.

Go를 배울 가치가 있을까

백엔드 서비스, 명령줄 도구, 또는 클라우드 인프라 분야의 무언가를 작성한다면 그렇습니다. 그 생태계의 상당 부분이 Go로 작성되어 있어서 그 소스를 읽는 것이 일의 일부입니다. 언어가 작으므로 투자도 크지 않습니다. 핵심 문법은 며칠이면 되고, 관용적인 동시성과 오류 처리는 몇 주 연습하면 익숙해집니다.

로컬에서 Go를 쓰기 시작하려면 Go를 설치한 뒤, 첫 프로그램의 모든 줄을 설명하는 hello world 페이지를 따라가 보세요.

자주 묻는 질문

Golang은 어디에 쓰이나요?

주로 백엔드와 인프라 소프트웨어입니다. 웹 서버와 API, 마이크로서비스, 명령줄 도구, 네트워크 코드, 클라우드 도구 등입니다. Docker, Kubernetes, Terraform, Prometheus가 모두 Go로 작성되었습니다. 데스크톱 GUI, 모바일 앱, 데이터 과학에는 거의 쓰이지 않습니다.

Go와 Golang은 같은 것인가요?

네. 언어의 이름은 Go입니다. "Golang"은 원래 웹사이트 주소인 golang.org에서 나왔고, "go"가 검색하기 어려운 단어라서 굳어졌습니다. 두 이름 모두 같은 언어와 같은 툴체인을 가리킵니다.

Go 프로그래밍 언어는 누가 만들었나요?

Robert Griesemer, Rob Pike, Ken Thompson이 2007년부터 Google에서 Go를 설계했습니다. 2009년 11월 오픈 소스로 발표되었고, Go의 호환성 약속이 시작된 릴리스인 Go 1.0은 2012년 3월에 나왔습니다.

Go는 배우기 쉬운가요?

언어 자체는 작습니다. 키워드 25개, 반복 구문 하나, 오후 한나절이면 읽을 수 있는 짧은 명세가 전부입니다. 다른 언어 경험이 있는 개발자 대부분은 며칠 안에 동작하는 Go 코드를 씁니다. 시간이 더 걸리는 것은 관용구입니다. 명시적인 오류 처리, 인터페이스, 그리고 고루틴과 채널로 올바른 동시성 코드를 작성하는 것입니다.

Go는 컴파일 언어인가요, 인터프리터 언어인가요?

컴파일 언어입니다. go build는 인터프리터나 가상 머신에 의존하지 않는 네이티브 기계어 바이너리를 만듭니다. go run도 컴파일합니다. 임시 위치에 빌드한 뒤 결과를 실행할 뿐입니다.

Coddy programming languages illustration

Coddy로 코딩 배우기

시작하기