Go
설치
asdf plugin add golang
정보
go get
이나 go install
을 사용한 후에는 asdf reshim golang
명령어를 실행해야 합니다.
Setup
mkdir <package>
cd <package>
go mod init <package>
private 패키지나 public 패키지로 만들 계획이 있는 경우 코드가 저장될 리포지토리의 경로를 <package>
로 사용해 야합니다. 자세한 사항은 Custom 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 <ld>
<ld>
-s
: static linking
-tags <tag>[,<tag>]
- https://pkg.go.dev/cmd/[email protected]#hdr-Build_constraints
//go:build <tagCondition>
에 true로 평가할 태그를 선언합니다.<tagCondition>
은 괄호()
, 논리 연산자&&
,||
,!
, 태그 이름으로 구성됩니다.
Ex) CGO_ENABLED=0 GOOS=darwin GOARCH=amd64 go build -a -ldflags '-s' -o app
정보
사용 가능한 GOOS
와 GOARCH
는 go tool dist list | column -c 75 | column -t
명령어로 알 수 있습니다.
go install
빌드된 바이너리가 GOBIN
경로에 설치됩니다.
Project Layout
- https://github.com/golang-standards/project-layout
- https://github.com/golang-standards/project-layout/blob/master/README_ko.md
처음엔 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는 목적을 정확하게 설명하는 이름을 붙입니다.
- 하나의 메서드만 가지는 interface는 일반적으로
- 에러 타입은
Error
로 끝나고, 에러 변수는Err
로 시작합니다. - package
- 의미 있는 단어를 사용하되 util, common 등의 이름은 피하세요.
- 복수형을 사용하지 마세요.
- 대문자를 사용하지 않습니다.
- path의 마지막 컴포넌트와 package 명은 동일해야 합니다.
- pakcage 위에 주석을 달아주는 것이 좋습니다.