저장소, 모듈, 패키지
- 저장소
- 깃허브와 같은 버전 관리 시스템의 공간이다.
- 모듈
- 저장소에 저장된 Go 라이브러리나 응용 프로그램의 최상위 루트이다.
- 모든 모듈은 전역적으로 유일한 식별자를 가지고 있어야 한다.
- 패키지
- 모듈 구성 및 구조를 제공한다. 모듈은 하나 이상의 패키지로 구성되어 있다.
go.mod
- 루트 디렉토리에 유효한 go.mod 파일이 있어야 모듈이 된다.
module github.com/my_module_name
go 1.19 // Go의 최소 호환 버전 지정
require ( // 해당 모듈이 의존하는 모듈과 각 모듈에 필요한 최소 버전을 나열한다.
entgo.io/ent v0.11.4
github.com/cloudflare/cfssl v1.6.3
...
)
// 의존성 있는 모듈이 있는 위치를 재정의한다.
replace github.com/my_module_name/common v0.0.0 => ../../common
// 툭종 버전의 모듈 사용을 막을 수 있다.
exclude MODULE_NAME vx.x.x
cmd 디렉토리
- 모듈이 하나 이상의 응용프로그램으로 구성되었다면, 모듈의 루트 드렉터리에
cmd
디렉토리를 만들어 구분할 수 있다. → Go의 관례이다.

내부 패키지 - internal
- 모듈에서 패키지간의 함수, 타입, 상수를 공유하고 싶지만, API의 일부가 되게는 하고 싶지 않은 경우 internal 패키지 이름을 통해 이것을 지원한다.
- 패키지를 외부 노출시키고 싶지 않을 때 internal 폴더 안에 패키지를 위치시킨다.
- internal 패키지와 해당 패키지 안의 식별자들은 internal과 같거나 한 단계 높은 레벨의 디렉터리에서만 접근 가능하다.
패키지 주석과 godoc
- Go는 자동적으로 문서로 변환해주는 조석을 작성하기 위한 포맷을 가진다. 이를
godoc
이라고 한다. - 항목의 선언과 주석사이에 빈 줄 없이 주석을 작성한다.
- 두 개의 슬래시와 항목의 이름으로 주석을 시작한다.
- 여러 단락으로 주석을 나누기 위해서는 빈 주석라인을 사용한다.
// Load will read your env file(s) and load them into ENV for this process.
//
// Call this function as close as possible to the start of your program (ideally in main)
//
// If you call Load without any args it will default to loading .env in the current path
//
// You can otherwise tell it which files to load (there can be more than one) like
//
// godotenv.Load("fileone", "filetwo")
//
// It's important to note that it WILL NOT OVERRIDE an env variable that already exists - consider the .env file to set dev vars or sensible defaults
func Load(filenames ...string) (err error) {
filenames = filenamesOrDefault(filenames)
for _, filename := range filenames {
err = loadFile(filename, false)
if err != nil {
return // return early on a spazout
}
}
return
}
godoc
은 go 프로그램의 문서를 생성하게 해준다. → swagger같이
init 함수
init 함수
- 명시적으로 아무것도 하지 않아도 패키지에서 상태를 설정하는 방법으로 init 함수을 사용할 수 있다.
- 다른 패키지가 init이 있는 패키지를 처음 참조하는 순간 수행된다.
- 주로 데이터베이스 드라이버 등록과 같은, 단일 할당으론 불가능한 패키지 레벨 변수를 초기화 하는 경우에 사용한다.
- 이 경우, 가져오는 패키지 앞에 밑줄(_)을 이름으로 할당하여 공백 가져오기를 허용한다.
- init 함수를 수행하지만, 노출된 식별자에 대한 접근은 허용하지 않는다.
import (
"database/sql"
_ "github.com/lib/pq"
)
순환 의존성
- Go는 순환 의존성을 허용하지 않는다.
- A 패키지가 B 패키지를 직/간접적으로 가져왔다면, B 패키지도 A 패키지를 가져올 수 없다.
- 이런 경우 두 패키지를 하나로 합치거나, 순한 의존성을 유발하는 항목만 통합하여 새 패키지로 이동시켜 해결하자.
모듈
- Go는 서드 파티에서 가져온 코드와 본인이 작성한 코드 모두를 컴파일하여 단일 바이너리로 만든다.
- 서드 파티든 본인의 코드든 모두
import
구문으로 가져온다.
- 모듈 버전과 mod 명령어
- 기본적으로 모듈을 프로젝트에 추가하면 의존성의 최신 버전을 선택한다. 하지만 이전 버전도 선택이 가능하여 버전 관리를 유용하게 할 수 있다.
go list
명령어를 통해 프로젝트에 사용된 패키지들을 확인할 수 있다.go get
명령어는 모듈과 관련된 작업과 의존성 업데이트를 할 수 있다.go get
golang.org/x/tools/cmd/godoc
@v1.0.0
go.mod
와go.sum
go.mod
파일에는 현재 모듈에서 사용하고 있는 버전들만 명시되어 있다.- 하지만
go.su
m
파일에는 이전에 사용했던 모듈들의 버전도 모두 기록되어 있다. go mod tidy
- 프로젝트에서 모듈 의존성을 정리하고 최적화한다.
go.sum
파일에도 해당 모듈의 사용된 버전만 관리되어, 버전 충돌을 방지한다.go mod vendor
- 해당 모듈에 의존하는 모든 패키지를 프로젝트 내부의 vendor 디렉토리로 복사한다.
- 인터넷이 연결되어 있지 않는 환경 등에 사용한다.
- pkg.go.dev
- Go 팀에서 만든, 오픈소스 Go 프로젝트를 자동으로 인덱싱하는 사이트.
- 모듈을 위한 프록시 서버
go get
명령을 하면, 기본적으로 깃허브와 같은 소스 저장소에서 직접 가져오는게 아니라, 구글에서 수행하는 프록시 서버에서 처리한다.- 프록시 서버 외에도 집계 데이터베이스를 관리하는데, 모듈들의 버전과 체크섬을 정보를 포함한다.
go build, go get
등의 명령어로 모듈을 다운받을 때마다, 해시를 계산하고 집계 데이터베이스에 접근하여, 해시가 일치하지 않으면 모듈은 설치되지 않는다.
- 비공개 저장소(GOPRIVATE)
- 비공개 저장소에 저장된 조직의 코드를 가져오고 싶은 경우, 이 경우 프록시 서버로 모듈을 요청할 수 없다.
- 이 경우 GOPRIVATE 환경 변수를 사용하여 repo를 지정해주면, 인증된 사용자만이 해당 패키지를 가져올 수 있다.
export GOPRIVATE='github.com/{{your private repo}}/'
Share article