Skip to main content

Go


Installation

asdf plugin add golang
asdf list all golang
asdf install golang 1.19.2
asdf global golang 1.19.2
asdf local golang 1.19.2
asdf current golang
info

go get이나 go install을 사용한 후에는 asdf reshim golang 명령어를 실행해야 합니다.

Setup

mkdir <package>
cd <package>
go mod init github.com/<user>/<package>
go mod tidy

모듈의 소스코드와 go.mod 파일을 비교하여 모듈을 추가 또는 제거합니다.

Build

[envs] go build [flags] [-o <output>]
  • [envs]
    • GOOS=<os>
    • GOARCH=<arch>
    • CGO_ENABLED=0|1: cgo 사용 여부
  • [flags]
    • -a: 사용되는 모든 패키지를 강제로 다시 빌드합니다.
    • -ldflags 'flags'
      • flags
        • -s: static linking

Ex) CGO_ENABLED=0 GOOS=darwin GOARCH=amd64 go build -a -ldflags '-s' -o app

info

사용 가능한 GOOSGOARCHgo tool dist list | column -c 75 | column -t 명령어로 알 수 있습니다.

go install

빌드된 바이너리가 GOBIN경로에 설치됩니다.

Project Layout

처음엔 main.go로 시작한 후, 프로젝트가 성장함에 따라 리팩토링을 통해 구조화 해가는 것이 좋습니다.

  • /cmd
    • 메인 애플리케이션
    • /cmd/<command>/...: 디렉터리 명 == 실행파일 명
    • /cmd/<command> 내에서는 코드 작성을 최소화해야 합니다.
  • /internal
    • private 애플리케이션과 라이브러리
    • 다른 사람이 import 하기 원치 않는 코드
    • Go 컴파일러는 internal 이라는 디렉터리를 인식합니다.
  • /pkg
    • public 라이브러리
    • 다른 사람이 사용할 수도 있으므로 주의해서 코드를 추가해야 합니다.
  • /api
    • OpenAPI/Swagger 스펙, JSON schemas, 프로토콜 정의 등
  • /web
    • static assets, server side templates, SPA 등
  • /configs
  • /init
    • 시스템 init (systemd, upstart, sysv) 과 프로세스 매니저/슈퍼바이저 (runit, supervisord) 설정 등
  • /scripts
    • 빌드, 설치, 분석, 기타 작업을 위한 스크립트
    • 루트 디렉터리의 Makefile에서 스크립트를 호출하는 방식을 사용하여 가독성을 높일 수 있습니다.
  • /build
    • 클라우드, 컨테이너, 운영체제 패키지 설정과 스크립트를 /build/package에서 관리
    • CI 설정과 스크립트를 /build/ci에서 관리
  • /deployments
    • 배포 설정과 템플릿
    • /deploy를 사용하기도 합니다.
  • /test
    • 추가적인 외부 테스트 앱과 데이터
  • /docs
  • /tools
  • /examples
  • /third_party
  • /assets
    • 리포지터리와 함께 사용될 수 있는 이미지, 로고 등
  • /website
    • 프로젝트의 웹사이트 데이터

라이브러리의 경우 패키지 코드를 루트 디렉토리에 두는 경우가 있습니다. import path에 리포지터리 구조가 노출되어야 하거나 불필요한 경로가 없도록 해야합니다.

Name Convention

  • 일관성, 간결성, 정확성
  • 카멜케이스
  • private은 소문자로 시작하고, public은 대문자로 시작합니다.
  • 선언 위치와 사용 위치가 멀어질 수록 이름을 길게 하는 것이 좋습니다.
    • index -> i, reader -> r, buffer -> b 등으로 줄여 쓰는 것이 좋습니다.
    • 이름이 길어야지 이해되는 코드가 있다면 리팩토링이 필요할 수 있습니다.
  • 축약어는 모두 대문자로 씁니다.
  • 중복 될 수 있는 이름은 피합니다. server.ServerRun -> server.Run
  • func
    • 파라미터: 타입만으로 추측이 가능하다면 가능한 짧게, 추측이 어렵다면 충분히 설명할 수 있도록 합니다.
    • 리턴: 타입이나 함수명으로 추측이 안되는 경우에만 이름을 씁니다.
    • Receiver: 한 개 또는 두 개의 문자로 이름을 짓고, 한 번 사용한 이름을 일관되게 사용해야 합니다.
    • Must로 시작하는 함수의 경우 실행에 문제가 있을 때, panic을 발생시킵니다.
  • interface
    • 하나의 메서드만 가지는 interface는 일반적으로 er을 마지막에 붙입니다. 말이 안되는 단어가 되더라도 붙입니다.
    • 여러 메서드를 가지는 interface는 목적을 정확하게 설명하는 이름을 붙입니다.
  • 에러 타입은 Error로 끝나고, 에러 변수는 Err로 시작합니다.
  • package
    • 의미 있는 단어를 사용하되 util, common 등의 이름은 피하세요.
    • 복수형을 사용하지 마세요.
    • 대문자를 사용하지 않습니다.
    • path의 마지막 컴포넌트와 package 명은 동일해야 합니다.
    • pakcage 위에 주석을 달아주는 것이 좋습니다.

Reference