핵심 정리
package user
import "time"
type Profile struct {
ID string
createdAt time.Time
}Go에서는 같은 디렉터리의 파일이 하나의 package를 이루고, 대문자로 시작하는 이름만 외부 package에 공개됩니다.
기본 흐름
파일 첫 줄은 package 선언이다
package user같은 디렉터리에 있는 Go 파일은 보통 같은 package 이름을 가집니다. package는 import와 공개 API의 단위입니다.
internal/user/
model.go // package user
repository.go // package userimport는 module 경로 기준으로 읽는다
import "example.com/myapp/internal/user"내 프로젝트 안의 package를 import할 때는 go.mod의 module 경로가 기준입니다. 표준 라이브러리는 "fmt", "time", "net/http"처럼 짧은 경로를 씁니다.
대문자로 시작하면 exported name이다
type User struct {
ID string
name string
}User, ID는 다른 package에서 접근할 수 있습니다. name은 같은 package 안에서만 접근할 수 있습니다.
가져오기 형태
보통은 기본 import를 쓴다
import (
"fmt"
"time"
)여러 package는 import block으로 묶습니다. 사용하지 않는 import는 컴파일 오류가 됩니다.
alias는 이름 충돌이나 가독성 때문에 쓴다
import userrepo "example.com/myapp/internal/user/repository"alias import는 package 이름이 겹치거나 호출부 이름을 더 명확히 해야 할 때만 제한적으로 씁니다.
side effect import는 명시적으로 드러낸다
import _ "net/http/pprof"밑줄 import는 package의 init side effect만 필요할 때 씁니다. 자주 쓰는 패턴은 아니므로 이유가 코드에서 드러나야 합니다.
선택 기준
| 상황 | 먼저 떠올릴 선택 |
|---|---|
| 같은 책임의 코드 묶음 | 같은 package |
| 외부에 공개할 타입/함수 | 대문자로 시작 |
| 내부 구현 세부사항 | 소문자로 시작 |
| 표준 라이브러리 사용 | 짧은 import 경로 |
| 프로젝트 내부 import | module 경로 기준 |
| side effect만 필요 | _ import |
주의할 점
Go의 공개 범위는 public, private 키워드가 아니라 이름의 첫 글자로 결정됩니다. 타입은 exported인데 필드가 unexported이면 외부 package에서 직접 채울 수 없습니다. API로 노출할 구조체는 필드 공개 여부까지 같이 설계해야 합니다.
참고 링크
3 sources