Import 선언
Import 선언 (Import declarations)
한 프로그램 안에서 다른 패키지의 기능을 가져다 쓸 때, 우리는 그 패키지를 어떤 이름으로 부를지 정해요. 그 역할을 하는 게 바로 import 선언이에요. 이번에는 import 선언이 정확히 무엇을 하는지, 또 패키지를 여는 이름을 어떻게 지정하는지 하나씩 살펴볼게요.
출처: Go Specification
본문
import 선언은 그 선언이 담긴 소스 파일이 import된 패키지의 기능에 의존한다는 뜻이고, 그 패키지에서 exported 식별자들을 쓸 수 있게 해줘요(자세한 실행 순서는 §Program initialization and execution을 봐요). import 선언은 접근에 쓸 이름(PackageName)과, 가져올 패키지를 지정하는 ImportPath 이렇게 두 가지를 정해요.
구문은 이렇게 생겼어요.
ImportDecl = "import" ( ImportSpec | "(" { ImportSpec ";" } ")" ) .
ImportSpec = [ "." | PackageName ] ImportPath .
ImportPath = string_lit .
통째로 import를 하나씩 쓰거나, 괄호로 묶어서 여러 패키지를 한 번에 가져올 수 있어요. 각 ImportSpec은 선택적으로 . 또는 PackageName을 붙이고, 그 뒤에 ImportPath(문자열 리터럴)를 적어요.
PackageName은 qualified identifiers에서 그 패키지의 exported 식별자에 접근할 때 써요. 이 이름은 file block에 선언돼요. PackageName을 생략하면, import된 패키지의 package clause에 명시된 식별자가 기본값이 돼요. 이름 대신 명시적인 점(.)이 오면, 그 패키지의 package block에 선언된 모든 exported 식별자가 import하는 소스 파일의 file block에 선언돼서, 한정자(qualifier) 없이 그냥 이름만으로 접근해야 해요.
ImportPath가 어떻게 해석되는지는 구현에 따라 다르지만, 보통은 컴파일된 패키지의 전체 파일 이름에서 일부를 떼어낸 문자열이에요. 설치된 패키지들의 저장소를 기준으로 한 상대 경로일 수도 있어요.
여기에 구현 제한이 하나 있어요. 컴파일러는 ImportPath를 비어 있지 않은 문자열로 제한할 수 있고, 그때 쓸 수 있는 문자도 Unicode의 L, M, N, P, S 일반 범주(공백 없는 그래픽 문자들)에 속한 것들로 제한할 수 있어요. 또 !"#$%&'()*,:;<=>?[\]^{|}` 문자들과 Unicode 대체 문자(replacement character) U+FFFD도 제외할 수 있죠.
구체적으로 어떻게 달라지는지 표로 보면 바로 와닿을 거예요. package math라는 package clause를 담고, 함수 Sin을 export하며, "lib/math"라는 파일로 식별되는 컴파일된 패키지가 있다고 해볼게요. import 선언의 종류에 따라 Sin에 접근하는 로컬 이름이 달라져요.
| Import declaration | Local name of Sin |
|---|---|
import "lib/math" |
math.Sin |
import m "lib/math" |
m.Sin |
import . "lib/math" |
Sin |
import 선언은 import하는 패키지와 import된 패키지 사이의 의존 관계를 선언해요. 그래서 패키지가 자기 자신을 직접이든 간접이든 import하는 건 불법이고, exported 식별자를 하나도 참조하지 않은 채 다른 패키지를 직접 import하는 것도 불법이에요. 만약 오직 부수 효과(side-effects), 예를 들어 초기화(initialization)만을 위해 패키지를 가져오고 싶다면, blank 식별자를 명시적인 패키지 이름으로 쓰면 돼요.
import _ "lib/math"
더 알아보기
- Package clause — import 선언과 짝을 이루는 패키지 이름 선언
- Exported identifiers — 어떤 식별자가 다른 패키지에서 보이는지
- Qualified identifiers — PackageName으로 패키지 안에 접근하는 방법
- Program initialization and execution — import로 생긴 의존 관계가 실행 순서에 주는 영향
- Blank identifier — 부수 효과만 원할 때 쓰는
_