Published on
9 min read

Go는 캐릭터만 귀엽지 않습니다.

🏁 거창하게 시작하는 오늘의 글

내 언어의 한계는 내 세계의 한계를 의미한다.

  • 루트비히 비트겐슈타인

저명한 영국의 철학자, 비트겐슈타인의 문장 중 하나입니다.

새로운 언어를 배우는 것은 단순히 단어의 조합을 외우는 것을 넘어,
그 언어가 탄생한 문화, 사고 구조, 나아가 세계관을 배우는 일이라고 생각합니다.

결국 언어를 배우는 것은 나의 세계관을 넓히는 일이라고 생각해요.

그런데 이게 프로그래밍 언어와 무슨 상관이냐고요?

저는 프로그래밍 "언어"도,
비슷하다고 생각합니다.

📘 실용주의 프로그래머

실용주의 프로그래머라는 책입니다.

이 책에서도 다양한 언어를 접하는 것의 유용성을 언급하죠.

다른 언어는 동일한 문제를 다르게 푼다.
몇 가지 서로 다른 접근법을 알면 사고를 확장하고, 판에 박힌 사고에 갇히는 걸 예방하는 데 도움이 된다.

  • 실용주의 프로그래머, p22

저는 프로그래밍 언어와 외국어가 굉장히 유사하다고 생각합니다.

영어와 한국어는 같은 생각을 다른 단어로 표현하죠.
어순, 문법도 전혀 달라요.

"동일한 문제를 다르게 푸는 것"이죠.

최근 저는 Go라는 언어에 흥미를 느꼈습니다.
2주 정도 간단하게 공부를 해봤는데요.

간단한 CLI Todo list, 크롤러를 만들면서 느낀
Go라는 언어의 특징과 장점, 새로운 언어를 배우는 것의 유용성을
소개해 볼까 합니다.

⚙️ Golang의 특징

Go는 간결하고 빠른 언어입니다.
실용적이고, 명확하며, 단순하죠.

🍲 간결하고 명시적인 백숙같은 맛

func main() {
  foo := "Hello world"
  fmt.Println(foo)
}

콘솔에 Hello world를 띄우기 위한 코드입니다.

여러분이 프로그래밍 언어를 배워봤다면, 정말 빠르게 배울 수 있습니다.
변수 선언, 함수, if, for, switch문 모두 간결하죠.

🚀 실용주의

Go는 컴파일 언어입니다.
그치만, 컴파일 속도가 굉장히 빠릅니다.

게다가 모든 의존성을 포함해
하나의 실행 파일로 컴파일이 되기 때문에,
배포도 간편하죠.

정말 '개발자 친화적'인 언어라고 생각합니다.

🧵 동시성

Go는 병렬 프로그래밍을 쉽게 할 수 있도록 설계된 언어입니다.
비동기 로직을 쉽게 다룰 수 있죠.

package main

import (
	"fmt"
	"time"
)

// 무언가를 하는 함수 (예: API 호출, 파일 처리 등)
func doSomething(name string, done chan string) {
	time.Sleep(2 * time.Second)
	done <- fmt.Sprintf("%s 작업 완료!", name)
}

func main() {
	done := make(chan string)

	go doSomething("A", done) // 고루틴으로 실행
	go doSomething("B", done) // 또 하나의 고루틴 실행

	// 결과 받기
	fmt.Println(<-done)
	fmt.Println(<-done)
}

go 라는 키워드와 함께 함수를 호출합니다.

그리고 채널을 만들어, 고루틴이 결과를 주고받을 수 있게 하면,
간단하고 명확하게 동시에 실행할 수 있는 코드를 만들 수 있죠.

🧠 Go라는 언어가 사고방식에 끼친 영향

📌 포인터 개념의 명료화

Go를 배우기 전까지는 사실 포인터라는 개념을 잘 모르고 있었습니다.
그냥 '아, 이런 개념이 있구나' 정도로 어렴풋하게 알고 있었죠.

자바스크립트에서는 변수 참조와 복사를 경험적으로 체득해왔지만,
그 아래 메커니즘은 흐릿하게만 느껴졌습니다.

그런데 Go에서는 '포인터'라는 개념이 명시적으로 등장합니다.
처음에는 복잡하고 어렵게 생각했는데,
알면 알수록 '아 이래서 포인터가 있는 거구나' 생각이 들었죠.

덕분에 포인터에 대한 개념을 단단하게 다질 수 있었고,
자바스크립트와 같은 언어에서도, 참조와 복사를 저수준에서 이해할 수 있게 되었습니다.

🧯 에러는 숨기지 말고, 직면하라.

Go에서 인상 깊었던 것은 에러 처리 방식입니다.
대부분의 언어에는 try-catch가 있죠.

뭉텅이로 에러를 처리하는 방식인데요.

사실 이런 방식을 그렇게 좋아하지 않았습니다.
너무 넓은 범위에 try-catch를 사용하면,
정확히 어떤 부분에서 에러가 발생했는지 알기 힘들었죠.

Go는 에러를 반환값으로 명시하여 만듭니다.

package main

import (
	"errors"
	"fmt"
)

// string과 error를 반환하는 greet 함수
func greet(name string) (string, error) {
	if name == "" {
		return "", errors.New("이름이 없어요")
	}
	return "안녕, " + name, nil
}

func main() {
	msg, err := greet("")
	if err != nil {
		fmt.Println("에러:", err)
		return
	}
	fmt.Println(msg)
}

처음에는 번거로울 수 있지만,
이게 얼마나 명확하고 안전한 방식인지 알 수 있을 겁니다.

에러를 통제할 수 있다는 자신감을 가지게 되었죠.

에러를 숨기지 않고, 명확하게 들어내는 것.
프로그래밍에서뿐 아니라, 저의 삶에서도 유효한 저만의 철학이 되었습니다.

🎮 재미있는 코딩

Go라는 언어를 배우고 실습하면서 얻은 가장 큰 보물은
'즐거움' 이었습니다.

매일 코드를 보며 데드라인과 책임감의 압박으로
집에서는 코드를 안보기 시작했었는데요.

Go를 부담 없이, 그저 재미로만 공부를 하니
그동안 잊고 있던 코딩의 재미를 다시금 느끼게 되었습니다.

이제는 퇴근하고 와서도, 오픈소스를 구경한다던지,
어떤 기여를 할 수 있을지 찾아보고 있습니다...

다시 한번 순수한 재미를 느끼게 되었죠.

🎯 결론

Go는 새로운 기술이자 언어일 뿐만 아니라, 새로운 사고방식을 배울 수 있는 좋은 기회였습니다.
단순하고 명료한 언어와 사고방식, 그리고 그 속에서 얻은 즐거움들이 있었죠.

게다가 Go는 캐릭터가 굉장히 귀엽답니다?

그러니까 우리 함께 공부해보지 않을래요? 🐹🐹