Go Reference
Go 프로그래밍 레퍼런스
Go Reference 소개
Go 언어 레퍼런스는 Go 프로그래밍 언어의 핵심 문법과 표준 라이브러리 패턴을 정리한 종합 치트 시트입니다. Go의 고유한 설계를 반영하는 8가지 카테고리로 구성되어 있습니다: 기본문법(package, import, var, :=, const/iota, fmt, if/else, for, switch, defer), 자료형(배열, 슬라이스, make, 맵, 문자열, 포인터), 함수(func, 다중 반환값, 이름 있는 반환값, 가변 인자, 클로저), 구조체(struct, 메서드, 임베딩, 태그), 인터페이스(interface, 빈 인터페이스, 타입 단언, 타입 스위치, error), 고루틴(go, sync.WaitGroup, sync.Mutex), 채널(chan, 방향 채널, select, range), 패키지(go mod, errors, context, 제네릭).
Go는 백엔드 서비스, 클라우드 네이티브 애플리케이션, CLI 도구, 분산 시스템에 널리 사용됩니다. := 짧은 선언과 defer 동작을 배우는 입문자부터, 양방향 채널 방향 제약이나 errors.As/errors.Is 래핑 패턴의 정확한 문법을 찾는 경험 많은 개발자까지 모두에게 유용한 레퍼런스입니다. 한국어/영어 이중 언어를 지원하며, 코드 예제에는 문법 하이라이팅이 적용되어 바로 읽기 편합니다.
각 항목에는 정확한 문법 토큰 또는 키워드, 간결한 동작 설명, 실제 사용 예제가 포함되어 있습니다. Go 특유의 관용구를 특히 상세히 다룹니다: iota를 사용한 열거형 패턴, WaitGroup을 이용한 고루틴 생명주기 관리, select를 통한 채널 다중화, Go 1.18+ 타입 제약을 사용하는 제네릭. 현대 프로덕션 Go 코드를 반영하여 context 패키지의 deadline 전파 패턴도 포함되어 있습니다.
주요 기능
- var vs := 짧은 선언의 차이, iota를 활용한 열거형 패턴을 포함한 변수 선언 문법
- make(), append(), cap(), len(), nums[1:3] 부분 슬라이스 등 슬라이스 전체 동작 방식
- 리터럴 초기화, delete(), comma-ok 이디엄을 이용한 안전한 키 조회 등 맵 연산
- 값/포인터 리시버 메서드, 합성을 위한 임베딩, JSON 구조체 태그를 포함한 struct 정의
- 빈 인터페이스(any), 타입 단언, 타입 스위치, error 인터페이스를 포함한 인터페이스 타입
- go 키워드, sync.WaitGroup 조율, sync.Mutex를 이용한 안전한 공유 상태 관리 등 고루틴 패턴
- 버퍼/언버퍼 채널, 방향 제약(chan<-/<-chan), select 다중화, 닫힌 채널에서의 range 등 채널 패턴
- Go 1.18+ 제네릭(타입 파라미터, constraints.Ordered)과 context.WithTimeout을 이용한 데드라인 관리
자주 묻는 질문
var과 :=의 차이는 무엇인가요?
var은 패키지 스코프와 함수 내부 모두에서 사용할 수 있는 완전한 변수 선언이며, 명시적 타입 지정이 가능합니다(예: var name string = "Kim"). := 짧은 선언은 함수 내부에서만 사용 가능하며 타입을 자동 추론합니다(예: count := 42). 두 방식 모두 레퍼런스에서 예제와 함께 확인할 수 있습니다.
Go에서 다중 반환값은 어떻게 처리하나요?
Go 함수는 여러 값을 기본적으로 반환할 수 있습니다. 예: func divide(a, b float64) (float64, error). 호출 측에서는 result, err := divide(10, 3)으로 두 값을 함께 받습니다. 이 패턴은 다른 언어의 예외(exception)를 대체하는 Go의 표준 에러 처리 관용구입니다.
버퍼 채널과 언버퍼 채널의 차이는 무엇인가요?
언버퍼 채널(make(chan int))은 수신자가 준비될 때까지 송신자를 블로킹하여 동기화를 제공합니다. 버퍼 채널(make(chan int, 5))은 버퍼 용량까지 수신자 없이도 송신을 허용하여 비동기 통신을 가능하게 합니다. select 문으로 여러 채널을 다중화할 수 있습니다.
Go에서 defer는 어떻게 동작하나요?
defer는 함수 호출을 해당 함수가 반환되기 직전에 실행되도록 예약합니다. 주로 정리 작업에 사용됩니다: defer f.Close()는 에러로 인해 함수가 일찍 종료되더라도 파일이 항상 닫히도록 보장합니다. 여러 defer는 LIFO(후입선출) 순서로 실행됩니다.
고루틴은 스레드와 어떻게 다른가요?
고루틴은 OS가 아닌 Go 런타임이 관리하는 경량 사용자 공간 코루틴입니다. 시작 스택이 수 KB에 불과하며 하나의 프로세스에서 수천 개까지 확장 가능합니다. go 키워드로 실행하고(go myFunc()), sync.WaitGroup으로 완료를 기다립니다.
Go에서 인터페이스가 명시적 선언 없이 어떻게 동작하나요?
Go는 구조적(암시적) 타이핑을 사용합니다: "implements" 키워드 없이도 필요한 메서드를 모두 구현하면 인터페이스를 만족합니다. 예를 들어 Circle 타입에 Area()와 Perimeter() 메서드가 있으면 Shape 인터페이스를 자동으로 구현합니다. 이를 통해 덕 타이핑 스타일의 다형성을 활용할 수 있습니다.
Go 제네릭은 무엇이고 언제 사용하나요?
Go 1.18에서 도입된 제네릭(타입 파라미터)은 함수와 타입이 여러 타입에 걸쳐 동작하도록 합니다. 예: func Min[T constraints.Ordered](a, b T) T는 int와 string 모두에 동작합니다. 타입 안전성을 유지하면서 자료구조와 유틸리티 함수의 코드 중복을 제거할 때 사용합니다.
errors.Is와 errors.As를 이용한 에러 래핑은 어떻게 동작하나요?
fmt.Errorf("wrap: %w", err)는 에러 체인을 유지하면서 에러를 래핑합니다. errors.Is(wrappedErr, target)는 체인 내에 대상 값과 일치하는 에러가 있는지 확인하고, errors.As(wrappedErr, &appErr)는 체인 내에 대상 타입과 일치하는 에러가 있으면 포인터를 설정합니다. 이것이 Go의 관용적인 구조적 에러 처리 방식입니다.