Go(프로그래밍 언어)
(♥ 0)
[각주]
1. 개요[편집]
package main
import "fmt"
func main() {
fmt.Println("Hello, world!")
}
2009년 11월에 구글에서 처음 발표된 후 2012년 3월에 정식 발표된 프로그래밍 언어.
로버트 그리즈머, 롭 파이크, 케네스 톰슨[3] 이 디자인하였다. 2007년 경에 이들 세 사람이 새로운 언어에 대한 스케치를 하면서 프로젝트가 시작되었다고 한다. 세 사람 다 C++의 복잡함이 싫어서 Go를 만들었다고 한다. 지금도 패키지에 무엇을 포함할지는 이 세 사람이 만장일치로 합의해야 이뤄진다고 한다.
이름이 이름인만큼 검색이 불편한 경우가 제법 있다. 그래서인지 보통 Golang(고랭, Go 언어)으로 검색하거나 발음하는 것이 수월하다.
Go 언어 사용자들을 고퍼(Gopher)라고 부르며, 고퍼들을 위한 연례행사인 고퍼콘(GopherCon)이 세계 각국에서 매년 열리고 있다.
(2023년 8월에는 한국에서도 고퍼콘 코리아라는 이름으로 열렸다. 기사 참조)
온라인 상으로 코드를 실행시켜 보고 싶다면 여기로.
2. 버전[편집]
2009년 11월에 첫 선을 보인 이래, 2012년 3월에 1.0 버전 발표에 이어 2015년 8월에 1.5 버전이 나왔다. 1.5 버전에서는 드디어 Go 컴파일러가 Go로 작성되었다.[4] 그 이전까지는 C언어로 작성되어 있었다. 자기 자신으로 구현된 컴파일러가 생겼다는 것은 개발 속도에 상당한 가속이 붙게 되었다는 뜻이라고 할 수 있다.[5] 2016년 2월 중순에는 HTTP/2가 기본으로 지원되고 템플릿 문법의 개선 등이 이루어진 1.6 버전이 출시되었고, 8월에는 컴파일 속도의 개선, 실행 퍼포먼스 향상, /x/net/context 패키지의 기본 패키지화 등이 이루어진 1.7 버전이 출시되었다.
2017년 2월 즈음에 32비트 MIPS 명령어 지원, 컴파일러 프론트엔드 추가[6] , 가비지 컬렉션 개선, Cgo의 오버헤드 개선[7] 등의 변경점이 있는 1.8 버전이 출시되었다. 1.8 릴리즈 노트
2018년 8월에 발표된 1.11 버전에서 모듈이라는 패키지 관리 기능이 추가되었다. 그동안 약점이었던 패키지 버전 관리가 해결되었다. 그 대신 Windows XP와 Windows Vista를 더이상 지원하지 않는다.
1.16 버전부터 GOPATH가 먹히지 않는다. 모듈이 기본 옵션이 되어(GO111MODULE이 on), GO111MODULE 환경변수를 auto나 off로 하면 GOPATH를 사용할 수 있다. 1.17부터 모듈만 지원할 계획이었으나, go.mod가 있으면 모듈 없으면 gopath를 사용한다. 어쨌든 GOPATH와 non-modular 구조는 더 이상 사용되지 않으므로(deprecated) 모듈 구조를 사용하는 것이 권장된다. 참고자료.
Windows에서 버전 업데이트 시 사용하고자 하는 버전의 msi 파일만 설치하면 기존 버전의 삭제와 신규 버전의 설치가 함께 이루어진다.
3. 특징[편집]
3.1. 장점[편집]
Go 언어의 특징은 컴파일 언어이지만 컴파일러의 컴파일 속도가 매우 빨라 인터프리터 언어처럼 쓸 수 있다는 점에 있다.[8] 이는 언어의 문법 구조를 개선함으로써 달성하였다. 컴파일러가 소스 코드를 해석하는 pass 수를 줄여서 달성한 것으로 보인다. 접근하기 어렵지 않고, 코드 역시 간결하면서도 컴파일 언어답게 높은 성능을 낼 수 있다는 점이 호평을 받는다. 자료형 체계에 있어 정적 타입(static type) 검사가 이루어지는만큼, Python 등에 익숙해져 있다가 넘어올 경우 조금 애로사항이 꽃필 수 있다. 간결하게 코드를 작성할 수 있으면서도 풍부한 라이브러리 덕택에 막강한 기능을 쉽게 구현할 수 있다는 것은 큰 장점이다.
그러나 컴파일 언어의 태생적인 한계를 극복한 것은 아니라서 대형 모듈을 이것저것 붙이면 컴파일에 필요한 시간이 있기에 Python 등의 인터프리터 언어보다는 기계어 번역 시 확실히 반응이 느릴 수밖에 없다. 물론 컴파일 언어 중에서는 매우 빠른 편이지만 아무래도 인터프리터 언어의 즉흥성까지 바라는 건 무리. 대신 컴파일 언어인만큼 실행 시 퍼포먼스는 확실하다.
또한 Go는 Goroutine(이하 고루틴)이라는 비동기 메커니즘을 제공한다. 이 비동기 메커니즘은 Erlang에서 영향을 받은 것으로 각각의 고루틴은 병렬로 동작하며 메시지 채널을 통해 값을 주고받는다. 고루틴을 사용하면 이벤트 처리, 병렬 프로그래밍 등이 간단해진다. 단, 병렬화된 고루틴의 동기화 문제는 프로그래머가 다뤄야 하며 동기화를 무시할 경우 프로그램이 비정상 종료될 수도 있다. 예를 들어 부모 루틴이 자식 루틴보다 먼저 끝나버리면 자식 루틴은 OS에 의해 메모리에서 강제로 사출되어 버린다. 그래도 동기화 방법은 기존 멀티스레드 응용프로그램에 비해 매우 간단한 편. 단순히 고루틴으로부터 반환값을 받는 코드를 메인 스레드에 추가하면 된다.
고루틴은 멀티스레드 메커니즘이지만 자체적인 스케줄러에 의해 관리되는 경량 스레드이며 OS에서 관리하는 경량 스레드보다 더 경량이다.[9] 따라서 고루틴은 CPU 코어수와 무관하게 수백, 수천의 고루틴을 작성해도 효율적으로 동작한다. 이는 고루틴에 영감을 준 병행 프로그래밍 언어 Erlang도 마찬가지.
Go는 바이너리 컴파일러이므로 서로 다른 머신 플랫폼들을 타겟으로 배포해야 할 경우 환경변수(GOOS와 GOARCH 등)를 그에 맞게 설정한 후 컴파일해서 여러 벌의 배포판을 만들어야 한다.
Go는 명시하고 있지 않지만 단순함과 실용성을 지향하는 언어다. keyword가 25개밖에 되지 않고 문법 또한 간결해 입문이 쉬운 편이다.
보면 알겠지만 goto도 있으며, 예약어로만 존재하고 기능이 없는 Java의 goto와는 달리 실제로 C의 goto처럼 사용할 수 있다. 그러나 반쯤 숨겨둔 기능.
컴파일 언어인 덕분에, 속도가 느린 스크립트 언어에서 연산 퍼포먼스가 필요한 부분을 Go로 대체해 넣을 수도 있다. 예를 들면, Go로 만든 코드를 공유 라이브러리로 컴파일해 Ruby에서 FFI를 이용해 컴파일한 .so 파일을 가져와 사용하는 식. PHP에서도 역시 가능하다.[10] 다만 기본 패키지들은 대개 성능보다는 편의성에 초점을 맞춘 탓에 극한의 성능을 추구하는 경우라면 사용을 권하기 어려운 것들이 있다. 예를 들면 웹 서버 제작시에 쓰이는 net/http나 html/template 등이 그러한데, 이런 경우엔 기본 패키지를 대체하는 별도의 패키지를 이용하면 (실제 체감효과는 별론으로 하되) 벤치마크상으로는 심지어 수십 배나 수치가 좋아지는(...) 경우도 있다.[* 예를 들어 html/template의 경우 성능 저하의 주범으로 여겨지는 reflect를 사용해서 템플릿을 생성할 때 (코드 작성자 입장에서는 할 일이 줄어서 편리하지만) 자동으로 모두 이스케이프 처리를 해서 렌더링을 하므로 속도가 느려지게 된다. 당연하지만 이런 대체 패키지들을 쓰게 되면 대신 코드 작성은 조금 귀찮아지게 되고, 또한 기본 패키지의 문법이 호환되지 않는 경우도 잦다. 다만, 실제 서비스를 구성할 때에는 통상적으로 템플릿 캐싱을 추가할 것이므로 느린 파싱 속도는 사실 문제가 되지 않는다. net/http의 경우에도 NGINX 못지 않은 성능을 보여주는 대체 패키지인 fasthttp가 존재한다. 이런 물건들을 사용한 몇몇 프레임워크들은 유독 벤치마크 그래프가 하늘을 뚫을 기세로 눈에 띈다.(...)
3.2. 단점[편집]
바이트코드를 생성하는 언어가 아니므로, 바이너리만 배포할 경우 C/C++ 프로그램이 그렇듯 해당 타깃 머신에 맞춰서 각각 컴파일해야 한다. 그렇게 하지 않고서 다중 플랫폼을 지원하려면 소스 코드째로 배포해야 한다.
Go 언어의 설계 지향점은 시스템 프로그래밍 언어였지만, 가비지 컬렉션 개념이 존재하는 등, 운영 체제나 하드웨어에 근접하는 수준의 프로그래밍에는 적합하지 않아 C/C++을 대체할 수 있는 언어는 아니라는 것에 합의가 이루어지고 있는 상황이다. 실제로 고성능 연산에 사용하기에는 C/C++에 비해 느리며, 저수준 시스템 개발에서는 가비지 컬렉션과 고루틴을 지원하기 위한 무거운 런타임 등으로 인해 사용이 불가능에 가깝다. 그런 이유로 대체로 개발 속도와 실행 속도, 병행성 사이의 적정 지점이 필요한 서버 애플리케이션 개발에 많이 사용되는 편.
또 다른 비판점 하나로는 현대 프로그래밍 언어 연구의 성과를 일절 무시한 언어 설계. 많은 종류의 프로그램 버그는 프로그래밍 언어 차원에서 원천적으로 차단될 수 있으며, 프로그래밍 언어 연구자들은 쓰기 쉬우면서도 최대한 많은 버그를 컴파일 시점에 잡을 수 있는 타입 시스템[11] 을 만드는 데 많은 노력을 기울이고 있다. 하지만 이런 노력들이 무색하게 Go에서는 널 포인터나 안전하지 않은 타입 캐스팅의 유발 등 수많은 버그의 원천들에 전혀 손을 대지 않았다는 것.[12] 물론 단순성을 중시하는 Go의 철학상 최첨단 연구 성과들을 즉시 도입하는 데에는 무리가 있겠지만, 3~40년 전의 연구를 기반으로 최근 업계에서 당연하게 여겨지는 원칙들조차 전혀 고려하지 않았다는 것은 수많은 사람들에 의해 비판받은 바 있다. (첨언하자면 위 비판의 깃허브를 확인해보면 대부분 3년전에서 크게는 7년전 자료이므로 참고용으로만 보는게 맞아보인다.)
이에 대해 구글은 일반화(제네릭) 프로그래밍을 지원하면 코드가 더 간결해지지만 Go는 지금도 코드가 긴 편이 아니고, 컴파일 속도와 실행속도가 느려지기 때문에 아직 지원하지 않는다고 밝혔으나, 2021년경 일반화 프로그래밍을 지원하겠다고 발표, 결국 2022년 2월에 릴리즈된 1.18부터 제네릭을 지원하고 있다. #
코틀린처럼 Go 또한 변수 선언 후 이름 뒤에 타입이 붙는데 이 또한 프로그래밍에 익숙한 사람 기준 상당히 거부감이 든다고 표현하는 사람들이 많다.
4. 예시[편집]
Go는 탭(<TAB>) 문자로 들여쓰기를 하는 것이 원칙이다. #
package main // main() 함수를 포함하는 패키지의 이름이 main이 아닐 경우 에러가 발생한다.
import "fmt"
func main() {
fmt.Println("Hello, world!")
}
- Example of Printf
package main
import "fmt"
func main() {
fmt.Printf("%d %d\n", 32, 132);
}
- Hello world example of Cgo[13]
package main
/*
#include <stdio.h>
*/
import "C"
func main() {
C.puts("Hello world!")
}
- Example of goroutine: http
package main
import (
"fmt"
"net/http"
)
var c = make(chan *http.Response)
func head(url string) {
resp, _ := http.Head(url)
c <- resp
}
func main() {
// HEAD 요청을 동시에 실행한다.
go head("https://namu.wiki")
go head("https://www.google.com")
go head("https://golang.org")
for i := 0; i < 3; i++ {
resp := <-c
if resp != nil {
resp.Body.Close()
fmt.Printf("%v: %s\n", resp.Request.URL, resp.Status)
continue
}
fmt.Printf("%v: 연결 실패\n", resp.Request.URL)
}
}
- Example of select statement: timeout
package main
import (
"fmt"
"net/http"
"time"
)
func main() {
c := make(chan string)
go func() {
resp, err := http.Head("https://namu.wiki")
if err == nil {
resp.Body.Close()
c <- resp.Status
return
}
c <- "연결 실패"
}()
// 연결 시간 초과 알림을 select로 구현할 수 있다.
select {
case status := <-c:
fmt.Println(status)
case <-time.After(2 * time.Second):
fmt.Println("시간 초과")
}
}
5. 사용한 사례[편집]
나온 지 5년 동안은 구글에 취직이라도 하지 않는 이상[14] 배워봤자 딱히 쓸 데가 없다는 이유로 새로운 언어에 관심이 많은 얼리 어답터 개발자들 사이에서나 알음알음 쓰이던 정도였지만, 다름아닌 구글 출신 개발자들이 만든 것이기도 하고, 언어 자체가 가진 매력도 있어서 사용자 층이 점차 늘어나는 추세다. 특히 Go 언어를 이용해서 안드로이드와 iOS 앱을 제작할 수 있게 적용 중이다.[15] 또한 Python이 그렇듯 웹 개발에도 쓰이고 있고, Revel, Beego 등의 풀 스택 프레임워크나 Gin 등의 마이크로 프레임워크들이 인기를 끌고 있다. Martini는 한국어 문서도 있다. 특히 서버 사이드 언어로서 좋은 평가를 받고 있는데, 대형 서비스가 아닌 간단한 웹사이트의 경우 Go가 자체적으로 지원하는 라이브러리와 Gorilla 같은 툴킷만으로도 쉽게 웹사이트를 만들어낼 수 있다. 최근에는 Gin이나 echo 등의 웹 프레임워크도 활발히 사용되는 중이다.
컨테이너 기반 가상화 도구인 Docker, Kubernetes를 작성하는 데 사용된 언어로 유명하다. 마찬가지로 Cloud Native Computing Foundation (CNCF) 생태계에 속한 오픈소스 대부분이 Go 언어로 작성되어있는 만큼 특히 DevOps 분야에서 Go 언어를 채택하는 업체가 늘어나고 있다.
그리고 전부를 Go로 만든 것은 아니지만, 당연히 구글을 비롯해 드롭박스나 클라우드플레어[16] , 사운드클라우드 등에서도 기존의 기능들 중 상당수를 새롭게 Go를 이용해 바꿨다고 한다. 트위치도 많은 부분이 Go로 작성되었다고 하며, 언론사인 뉴욕 타임즈에서도 Gizmo라는 API 백엔드 서비스를 Go를 이용해 만들어 그 소스를 GitHub에 공개한 바 있고, SpaceX에서도 원격 측정 프로그램에서 Go를 사용한다고 한다. 또한 이더리움의 메인 클라이언트인 Geth 역시 Go로 작성되었고, Discord 또한 2020년 기준 최근 Rust로 교체 전까지는 서버와 클라이언트단 언어에 Golang을 채택하고 있었다. 즉 Go는 이미 시장에서 인정받은, 안정성이 검증된 언어라고 할 수 있다.
pkg.go.dev[* 구 GoDoc]이라는 Go 패키지 호스팅 사이트도 존재한다.
최적화가 잘 되어있다는 점 때문에, 코딩 테스트를 치르는 일부 프로그래머들이 계속 타임아웃 에러가 발생할 경우 원래 쓰던 언어 대신 Go로 풀이를 재작성해 제출하는 경우도 있다. 단, 이러려면 두 언어를 그만큼 능숙하게 다룰 줄 알아야 한다.
암호화폐 코스모스 아톰의 기본 프레임 워크 Cosmos SDK도 Go로 만들었다.
Wails라는 일렉트론의 대체제가 있는데, 프론트엔드로는 JavaScript를, 백엔드로는 Go를 사용한다.
Fyne이라는 크로스플랫폼 GUI 프레임워크가 있는데, Go 언어로 개발되었다.
6. Go를 지원하는 개발 도구[편집]
Go를 지원하는 통합 개발 환경(IDE)으로는 JetBrains의 GoLand, 또는 IntelliJ IDEA의 Go 플러그인이 가장 높은 평가를 받는다. 대신 학생인증이라도 받지 않는 이상 유료다. 무료 IDE를 찾는다면 Visual Studio Code에 Go 플러그인을 설치하여 사용하면 된다. 또는 이클립스나 LiteIDE라는 선택지도 있다.
7. 마스코트[편집]
Go 언어는 고퍼(Gopher, 흙파는쥐과의 동물)이라 부르는 상징적인 마스코트로도 잘 알려져있다. 다른 프로그래밍 언어는 추상적인 로고는 존재할지라도 마스코트라고 할 수 있는 동물이나 캐릭터가 없는데 반해 Go 언어는 고퍼 캐릭터가 존재하고 검색 엔진을 통해 "Go Gopher"라고 검색하면 여러가지 베리에이션이 존재하는 것을 확인할 수 있다.
고퍼 캐릭터가 탄생한 일화를 들어보면, Go 프로젝트를 진행할 당시 로고가 필요했는데, 미국의 만화 작가이자 일러스트레이터인 Renée French가 자원해서 그리게 되었고 이후 2009년에 오픈소스 출시를 하며 고퍼가 마스코트로 사용되기 시작했다. 더 자세한 이야기는 이곳에서 확인할 수 있다.
참고로 고퍼 이미지들은 Creative Commons Attribution 4.0 라이센스를 사용하기 때문에 마스코트 원본 사용 시 Renée French에게 크레딧(출처 언급)을 주어야 한다.
8. 학습 자료[편집]
8.1. 도서[편집]
- Tucker의 Go 언어 프로그래밍 - 사실상 현재 국내에서 유통되는 유일한 Go언어 입문서이다.
8.2. 유튜브[편집]
- Tucker의 Go 언어 프로그래밍 - 위 책의 저자가 제작한 동영상 강의
8.3. 웹사이트[편집]
- Go 프로그래밍 입문
- golang.org 문서 한국어 번역 프로젝트
- Effective Go (공식 Go 가이드 사이트) 한국어 번역 사이트
- Go Playground
- Golang Weekly
- Awesome Go
- 예제로 배우는 Go 프로그래밍
- 구름EDU 한 눈에 끝내는 고랭 기초
9. 여담[편집]
2016년 중반부터 CMS와 Micro Service Architecture를 기반한 서비스를 필두로 사용 영역 및 점유율이 급격히 높아지고 있다. 2016년 1월과 2017년 1월을 비교했을때 점유율은 0.161%에서 2.325%로 순위는 54위에서 13위로 올랐다. 스택 오버플로우에서 실시한 2017년 미국 개발자들 대상 설문조사에서는 평균 연봉 1위(11만불)의 언어로 기록되기도 했다.[17]
2024년 8월 기준 2.03%이며 순위는 9위이다.
1.8 버전까지의 net 패키지에서 net.go를 열어보면, aLongTimeAgo라는 유닉스 시간 233431200의 값을 가지는 변수가 들어 있다. 오래전의 시각을 미리 설정해 둔 것.[18] 그런데, 이것이 라즈베리 파이에서 발생시키는 문제가 발견되어 일단 1.9 버전 마일스톤에서는 233431200에서 그냥 1로 수정될 예정이다.
9.1. Write in Go[편집]
겨울왕국의
10. 관련 문서[편집]
11. 관련 커뮤니티[편집]
이 문서의 내용 중 전체 또는 일부는 2024-08-20 23:11:28에 나무위키 Go(프로그래밍 언어) 문서에서 가져왔습니다.
[1] 메이저 업데이트는 2월과 8월 말쯤에 한다.[2] 릴리즈 정보는 이곳에서 확인할 수 있다.[3] 1943년생으로 데니스 리치와 함께 유닉스 운영체제와 C언어를 만든 인물. 그래서인지 전반적으로 C에서 영향을 많이 받았다.[4] 다만 이 때부터 컴파일에 걸리는 속도가 약간 떨어졌다는 불평을 흔히 찾아볼 수 있다. 벤치마크 자료들에 따르면 1.4.3 버전이 1.5나 1.6 버전보다 컴파일에 걸리는 시간이 2~3배씩이나 빠르다는 것들도 흔히 보인다. 2016년 8월에 배포될 1.7 버전에서 이 문제는 어느 정도 개선될 것으로 보인다. 사전 공개된 1.7 베타 버전에서는 컴파일 속도가 1.6.2 버전에 비해 3분의 2 이하로 줄어들었다는 벤치마크 자료들이 보인다. 이후 공식적으로 밝힌 바에 의하면 1.6 대비 1.7은 20~30%가 감소했다고 한다.[5] 부트스트래핑(Bootstrapping) [6] 약 15%가 빨라졌다고 한다.[7] 약 절반 수준으로 줄어든다고 한다.[8] 사실 C++의 컴파일 속도가 복잡한 문법으로 인해 매우 느린 것이다.[9] 고루틴 스택 사이즈는 약 8 kiB이며, 런타임에서 동작하므로 문맥 교환(Context Switching) 면에서 OS 스레드 대비 효율적이다.[10] 그 반대도 가능하다. PHP를 예로 들면, libphp7.so를 이용해 Go에서 PHP 코드를 불러와 실행하는 식이다.[11] 대표적인 예로 동적 타입 언어인 JavaScript를 컴파일 시 에러를 낼 수 있도록 바꾼 TypeScript가 있다.[12] 사실 이러한 구조는 Go의 모티브가 된 C도 동일하게 가지고 있다. 하지만 C는 20세기의 언어이고 Go는 21세기에 나온 언어라는 것이 문제.[13] Go의 C 코드를 위한 FFI(Foreign Function Interface)이다.[14] 구글 내부에서는 이걸 시스템 프로그램용으로 일부 사용하고 있다고 한다.[15] https://github.com/golang/go/wiki/Mobile[16] Go 기본 패키지 중 crypto 관련 처리 속도가 클라우드플레어 정도의 대형 서비스가 쓰기에는 최적화되지 않은 면이 있어 자체적으로 이 부분을 개선한 것을 배포하고 있기도 하다.(1.4 버전 기준)[17] https://stackoverflow.com/insights/survey/2017#top-paying-technologies[18] 스타워즈 4가 A long time ago, in a galaxy far, far away....라는 스타워즈 시리즈의 전통의 오프닝과 함께 미국에서 개봉된 시각이다.[19] 상용구 코드 참고.[20] IDE에서 프로그래밍 언어의 문맥(syntax)이나 의미론(semantics)의 부적절성, 오류 등을 귀뜸해 주는 유틸.[21] 근데 이클립스도 Go를 지원한다