패키지
패키지에 대해 알아보자.
패키지의 개념
컬렉션을 시작으로 인터페이스까지 코드의 효율성, 재사용을 위해 끝없이 묶는(모듈화) 연습을 했습니다. 변수들을 묶은 컬렉션, 객체 정보를 묶은 메소드, 기능을 묶은 함수, 메소드를 묶은 인터페이스들을 학습하면서 더 이상 없다고 생각했지만 이 모든 것을 묶은 ‘패키지’가 있습니다. 이렇게 한 파일로 작성된 패키지인 컴포넌트는 코드의 모듈화, 코드의 재사용을 가능
하게 합니다. 이미 우리는 코드 상단에 import "fmt"
라고 습관적으로 입력하면서 수 없이 써왔습니다. 이것은 우리가 기능을 만들고 구현하지 않아도 누군가 만들어놓은 코드를 재사용
한다는 것을 의미합니다.
패키지는 두 종류가 있습니다. 바로 main 패키지와 그 외 패키지
입니다. main 패키지를 제외한 모든 패키지는 개발자가 직접 작성하든 Go언어에서 제공하는 패키지든 똑같이 취급됩니다. 반면에, main 패키지는 컴파일러에 의해 특별히 인식
됩니다. 컴파일러는 main 패키지를 공유 패키지(라이브러리)가 아닌 실행(executable) 프로그램
으로 만듭니다. 자연스럽게 main 패키지 안에 main() 함수는 프로그램의 시작점(Entry point)이자 종료점이 됩니다.
따라서 그 외 패키지를 공유 라이브러리
로 만들 때에는 main 패키지나 main 함수를 사용하면 안됩니다.
패키지 만들기
Go언어는 강력한 내장 라이브러리
가 있기 때문에 필요에 따라 얼마든지 import해서 사용할 수 있습니다. 또한 프로그램을 개발할 때 개발자가 직접 필요한 기능을 구현한 패키지를 만들고 여러 파일들 사이에서 import해서 쓸 수 있습니다. 이렇게 패키지를 통해 코드를 모듈화 하고 코드의 재사용하는 것은 프로그램의 질적인 측면에서 굉장히 중요합니다.
따라서 패키지를 사용해 작은 단위의 컴포넌트를 작성하고, 패키지들을 활용해 프로그램을 작성하는 것이 개발자의 능력이고 권장 사항
입니다.
원래 Go언어는 GOPATH 환경변수에 설정한 경로를 통해 프로그램을 실행(컴파일)
합니다. 구름IDE는 컨테이너 생성과 동시에 GOPATH에 자동으로 작업 공간 경로가 설정
됩니다. 이는 하단 터미널에 go env를 입력
해보면 알 수 있습니다
GOROOT라는 것이 있는데 이 환경변수는 Go가 설치된 경로
를 나타내며, 표준 패키지
들이 있는 곳입니다.(/pkg)
우리가 확인해야 할 것은 GOPATH입니다. 위 그림에 GOPATH는 'workspace/go_package'로 자동 설정
되어 있습니다. ‘go_package’는 컨테이너를 생성할 때 만든 컨테이너 이름입니다. 패키지는 GOPATH로 설정된 경로의 ‘src’ 폴더에 만들어야합니다. 패키지 생성은 패키지와 같은 이름의 폴더를 만들고 그 안에 Go 파일을 만드는 것
입니다.(main 패키지 제외) 아래 그림을 보면 쉽게 알 수 있습니다.
패키지를 만들 때, src 폴더 안에 패키지 이름의 디렉터리를 만들면 됩니다. go 파일은 해당 디렉터리 안에 생성하고 작성합니다. 여기서 눈여겨 봐야할 점이 있습니다. 바로 함수 이름의 첫 글자입니다.
첫 글자를 소문자로 지정하면 패키지 안에서만 사용할 수 있습니다.
첫 글자를 대문자로 지정하면 외부에서 사용할 수 있습니다. 위 예시가 그렇습니다.
import "fmt"
import "runtime"
import "time"
import "math/rand"
or
import (
"fmt"
"runtime"
"time"
"math/rand"
)
전역 패키지 사용하기
전역 패키지 선언은 특별하게 사용하지 않아도 되는 용법이기 때문에 지금까지 사용하지 않았습니다. 전역 패키지는 import할 때 패키지 이름 앞에 '.'(점)을 입력하면 선언
됩니다. 이는 fmt.Println()
처럼 앞에 패키지 이름을 입력하는 것이 아니라 fmt.를 생략하고 Println()와 같이 사용
할 수 있습니다. 이는 함수, 변수, 상수에 동일하게 적용됩니다.
package main
import . "fmt"
func main() {
Println("Hello, Goorm!")
}
패키지 별칭
함수나 변수는 type문을 이용해 사용자 지정 형식으로 사용할 수 있습니다. 패키지도 아래와 같이 패키지 앞에 사용자 지정 이름을 붙여 사용하는 똑같은 용법이 있습니다. 이는 특히 Go언어에서 제공하는 패키지와 개발자가 직접 만든 패키지의 이름이 겹칠 때, 혹은 다른 사람이 만든 패키지와 이름이 겹칠 때 유용
하게 사용할 수 있습니다.
그리고 Go언어는 사용하지 않는 변수에 대해 굉장히 철저하다고 했습니다. 만약 선언만 해놓고 사용하지 않으면 런타임 에러가 발생
합니다. 패키지도 똑같이 import만 하고 사용하지 않으면 에러가 발생합니다. 이때 패키지 이름 앞에 '_'(언더바)를 입력하면 컴파일 에러가 발생하지 않습니다.
이 기능은 디버깅할 때 주석을 하지 않고도 유용하게 사용할 수 있습니다.
package main
import (
f "fmt"
_ "runtime"
)
func main() {
f.Println("Hello, Goorm!")
}