2016년 후반쯤 Go언어를 처음 접하고, 토이 프로젝트도 하면서 열심히 공부했던 기억이 난다.
오프라인 그룹 스터디도 만들어서 간단한 채팅 프로그램을 만들며 새로운 언어를 익혀갔는데… 그 뒤로 열심히 파이썬만 파느라 그만뒀다.

그러다가 이제 다시 Go언어를 시작 해보려고 한다. 그동안 대부분 파이썬으로 개발했었는데 좀 더 빠른 언어를 배워두면 적절히 활용할 수 있을 것 같다.

어쨌든 새로운 것을 시작하려면 뚜렷한 목표와 충분한 명분이 필요하다.
‘요즘 핫하다’, ‘어느 회사에서 쓴다더라’ 같은 말을 앞세우기 보다 스스로 직접 선택의 이유와 기준을 만드는 과정이 필요하다. 그래야 오래 지속할 수 있지 않을까?

이 책은 Go언어가 탄생한 이유와 Go언어를 만든 핵심 개발자들 이야기, Go언어와 다른 언어의 차이점과 장점들을 가볍게 알려준다.
본격적으로 Go언어를 시작하기 전에 가벼운 마음으로 읽어보는 것을 추천한다.


Go 언어를 만든 이유

구글이 필요해서 만들었겠지만 결국 시대의 요구에 따라 더 좋은 개발 환경과 더 빠른 프로그램을 만들기 위해 새로운 언어가 필요했을 수도 있다고 생각한다.
Go의 장점 중에 하나인 빠른 빌드 시간은 여러가지 측면에서 절약을 통한 생산성 향상을 불러올 수 있는 부분이다. 그리고 구글은 예점부터 이런 부분들을 해결하려고 많은 노력을 기울였겠지만 그 한계점이 결국 새로운 언어의 탄생으로 이어졌다.


Go 언어를 만든 사람들

Go언어 초기 멤버에는 C언어를 만든 ‘켄 톰슨’이 있었다는 사실을 알게 되었다. C언어가 1972년에 만들어졌다고 하는데 40년만에 새로운 프로그래밍 언어를 만드는 것이 정말… 음… 진짜 멋있다.

‘롭 파이크’라는 사람은 Newsqeak이라는 언어를 개발한 사람인데 이 사람은 동시성 부분의 연구만 30년 동안 진행한 사람이라고 한다. Go언어가 동시성 부분에 강한 이유가 여기서 조금 납득이 된다.

‘러스 콕스’라는 개발자는 어릴적부터 프로그래밍 신동이라고 불렸다고 한다;;;


Go 언어 특징

다음은 책에서 소개한 Go언어의 특징을 간략하게 요약했다.

  1. 클래스가 없고, 상속을 지원하지 않는다.
  2. 가비지 컬렉션 지원한다.
  3. 포인터는 있는데 포인터 연산을 지원하지 않는다.
  4. 변수 선언은 영어 문장처럼 자연스럽게 읽혀지기 위함이다.
  5. 문장 끝 세미콜론은 대부분 생략 가능하다.
  6. while문이 없고 for로 모두 가능하다.
  7. public, private 접근 제한자가 없고, 첫글자가 대문자로 시작하면 외부 모듈에서 접근할 수 있다.
  8. 변수를 선언하면 자동으로 미리 정의한 타입별 zero value로 초기화된다.
  9. 인터페이스를 지원한다. 인터페이스는 ‘메서드들의 집합’을 의미하기도 한다.
  10. switch문에 break를 사용하지 않는다.
  11. 함수는 func 키워드를 붙여서 선언하고, 변수 선언과 마찬가지로 영어 문장처럼 자연스럽게 읽혀진다.
  12. 두 변수에 들어 있는 값을 쉽게 바꿀 수 있다. a, b = b, c
  13. 포인터 연산이 없기 때문에 배열의 특정 부분을 참조하기 위해 슬라이스를 사용한다. 슬라이스는 메모리를 할당하는 방식이 아니라 참조하는 방식이다.
  14. defer 키워드를 이용해 미리 함수가 끝날 때 동작을 지정할 수 있다.
  15. 변수를 선언하고 사용하지 않으면 컴파일 에러가 발생한다.
  16. 명시적 형변환을 사용해야 한다.
  17. 단위 테스트를 위한 테스팅 라이브러리를 제공한다.


Go 언어의 동시성

동시성을 지원하기 위한 goroutine이 있다.
함수 앞에 go라고 붙이면 끝. 동일한 주소 공간에 다른 goroutine들과 함께 동시 실행되고, 스레드보다 가벼우며 스택 주소 공간의 할당이 적다.

func doSomething() {
  // pass
}

func main() {
  go doSomething()
}

Go언어는 스택을 링크드 리스트(linked-list)로 관리한다. 할당 받은 공간이 충분하지 않으면 추가로 스택을 늘려 달라고 요청해 늘리는 방식이다.

goroutine마다 스레드에 할당되지 않고 일부 커널 스레드로 멀티플렉싱(multiplexing)되어 스레드에 할당되는 방식이다.

goroutine 사이의 통신은 channel을 통해 이뤄진다. channel을 이용해 메모리를 공유해서 상대 goroutine으로 데이터를 전달할 수 있다. channel 타입은 chan 키워드로 정의하고, 채널의 데이터는 언어에서 제공하는 기본형이나 커스텀 타입도 가능한다.

goroutine 통신은 데이터를 보낼 때 받는 쪽이 동일 채널에 대해 받을 준비가 될 때까지 기다리고, 받을 때는 보내는 쪽이 동일 채널에 대해 전달할 준비가 될 때까지 대기한다.