패키지에 대한 자세한 정보

완료됨

Go의 패키지는 다른 프로그래밍 언어의 라이브러리 또는 모듈과 유사합니다. 코드를 패키지하고 다른 곳에서 재사용할 수 있습니다. 패키지의 소스 코드는 둘 이상의 .go 파일에 배포할 수 있습니다. 지금까지 main 패키지를 작성하고 다른 기본 패키지에 대한 몇 가지 참조를 만들었습니다.

이 섹션에서는 패키지의 정의에 대해 알아봅니다. 패키지를 만드는 방법과 외부 패키지를 사용하는 방법도 알아봅니다.

기본 패키지

이미 파악했을 수 있겠지만, Go에서 가장 간단한 프로그램도 패키지의 일부여야 합니다. 일반적으로 기본 패키지는 지금까지 사용해 온 main 패키지입니다. 프로그램이 main 패키지의 일부인 경우 Go는 이진 파일을 생성합니다. 해당 파일이 실행될 때 main() 함수를 호출합니다.

즉, main 패키지를 사용하는 경우 프로그램에서는 독립 실행형 실행 파일을 생성합니다. 하지만 프로그램이 main이 아닌 패키지의 일부인 경우 Go는 이진 파일을 생성하지 않습니다. 패키지 보관 파일(확장명이 .a인 파일)을 생성합니다.

Go에서 패키지 이름은 규칙을 따릅니다. 패키지는 해당 가져오기 경로의 마지막 부분을 이름으로 사용합니다. 예를 들어 Go 표준 라이브러리에는 복소수를 사용하는 데 유용한 코드를 제공하는 math/cmplx라는 패키지가 포함되어 있습니다. 이 패키지의 가져오기 경로는 math/cmplx이며 다음과 같이 가져옵니다.

import "math/cmplx"

패키지의 개체를 참조하려면 다음과 같이 패키지 이름 cmplx를 사용합니다.

cmplx.Inf()

패키지를 만들어 보겠습니다.

패키지 만들기

$GOPATH/src 디렉터리에 calculator라는 새 디렉터리를 만듭니다. sum.go라는 파일을 만듭니다. 트리 디렉터리는 다음 디렉터리와 같습니다.

src/
  calculator/
    sum.go

패키지 이름으로 sum.go 파일을 초기화합니다.

package calculator

이제 패키지에 대한 함수 및 변수 작성을 시작할 수 있습니다. 다른 프로그래밍 언어와 달리 Go는 패키지 외부 또는 내부에서 변수나 함수를 호출할 수 있는지를 나타내는 public 또는 private 키워드를 제공하지 않습니다. 하지만 Go는 다음과 같은 두 가지 간단한 규칙을 따릅니다.

  • 특정 항목을 프라이빗으로 하려면 이름을 소문자로 시작합니다.
  • 특정 항목을 퍼블릭으로 하려면 이름을 대문자로 시작합니다.

이제 만들고 있는 계산기 패키지에 다음 코드를 추가해 보겠습니다.

package calculator

var logMessage = "[LOG]"

// Version of the calculator
var Version = "1.0"

func internalSum(number int) int {
    return number - 1
}

// Sum two integer numbers
func Sum(number1, number2 int) int {
    return number1 + number2
}

해당 코드에서 몇 가지를 살펴보겠습니다.

  • logMessage 변수는 패키지 내에서만 호출할 수 있습니다.
  • Version 변수는 어디서든 도달할 수 있습니다. 이 변수의 용도를 설명하는 주석을 포함하는 것이 좋습니다. 이 설명은 패키지를 사용하는 모든 사용자에게 유용합니다.
  • internalSum 함수는 패키지 내에서만 호출할 수 있습니다.
  • Sum 함수는 어디서든 도달할 수 있습니다. 이 함수의 용도를 설명하는 주석을 포함하는 것이 좋습니다.

모든 것이 작동하는지 확인하기 위해 calculator 디렉터리에서 go build 명령을 실행할 수 있습니다. 이렇게 하면 이진 실행 파일이 생성되지 않습니다.

모듈 만들기

계산기 기능을 패키지 내에 배치했습니다. 이제 패키지를 모듈에 넣을 때입니다. Go 모듈은 일반적으로 관련 기능을 제공하는 패키지를 포함합니다. 패키지의 모듈은 Go가 그룹화한 코드를 함께 실행해야 한다는 컨텍스트를 지정합니다. 이 컨텍스트 정보에는 코드가 작성되는 Go 버전이 포함됩니다.

또한 모듈은 다른 개발자가 특정 버전의 코드를 참조하고 종속성으로 더 쉽게 작업할 수 있도록 도와줍니다. 또 다른 혜택은 프로그램의 소스 코드가 반드시 $GOPATH/src 디렉터리에 있을 필요가 없다는 것입니다. 이 제한이 없으므로 다른 프로젝트의 다른 패키지 버전으로 동시에 작업하는 것이 더 편리합니다.

따라서 calculator 패키지에 대한 모듈을 만들려면 루트 디렉터리($GOPATH/src/calculator)에서 다음 명령을 실행합니다.

go mod init github.com/myuser/calculator

이 명령을 실행하면 github.com/myuser/calculator가 모듈의 이름이 됩니다. 다른 프로그램에서 참조하기 위해 이 이름을 사용하게 됩니다. 또한 이 명령은 go.mod라는 새 파일을 만듭니다. 마지막으로 트리 디렉터리는 이제 다음 디렉터리와 같습니다.

src/
  calculator/
    go.mod
    sum.go

그러면 go.mod 파일의 내용이 다음 코드처럼 보입니다. (Go 버전이 다를 수 있습니다.)

module github.com/myuser/calculator

go 1.14

다른 프로그램에서 calculator 패키지를 참조하려면 모듈 이름을 사용하여 가져와야 합니다. 이 경우 이름은 github.com/myuser/calculator입니다. 이제 이 패키지를 사용하는 방법의 예를 살펴보겠습니다.

참고

지금까지 Go에서 종속성을 관리하는 것은 쉽지 않았습니다. 종속성 관리 시스템은 여전히 진행 중인 작업입니다. 모듈에 대한 자세한 내용은 Go 블로그에 게시된 게시물 시리즈를 참조하세요.

로컬 패키지(모듈) 참조

이제 패키지를 사용하겠습니다. 지금까지 사용한 샘플 애플리케이션을 계속해서 사용하겠습니다. 이번에는 main 패키지에서 sum 함수를 사용하는 대신 calculator 패키지에서 이전에 만든 함수를 사용하겠습니다.

이제 트리 파일 구조는 다음과 같습니다.

src/
  calculator/
    go.mod
    sum.go
  helloworld/
    main.go

$GOPATH/src/helloworld/main.go 파일에 이 코드를 사용할 것입니다.

package main

import (
  "fmt"
  "github.com/myuser/calculator"
)

func main() {
    total := calculator.Sum(3, 5)
    fmt.Println(total)
    fmt.Println("Version: ", calculator.Version)
}

import 문은 만든 패키지의 이름(calculator)을 사용합니다. 패키지에서 Sum 함수를 호출하려면 calculator.Sum과 같이 패키지 이름을 포함해야 합니다. 마지막으로, 이제 Version 변수에도 액세스할 수 있습니다. 이를 calculator.Version과 같이 호출합니다.

지금 프로그램을 실행하려고 하면 작동하지 않습니다. 다른 패키지를 참조 하는 모듈을 사용 하 고 있다는 것을 알려 주어 야 합니다. 이렇게 하려면 $GOPATH/src/helloworld 디렉터리에서 다음 명령을 실행합니다.

go mod init helloworld

이전 명령에서 helloworld는 프로젝트의 이름입니다. 이 명령은 새 go.mod 파일을 만들지만 이제 트리 디렉터리는 다음과 같습니다.

src/
  calculator/
    go.mod
    sum.go
  helloworld/
    go.mod
    main.go

go.mod 파일을 열면 다음 코드처럼 보입니다. (Go 버전이 다를 수 있습니다.)

module helloworld

go 1.14

모듈의 로컬 복사본을 참조하기 때문에 원격 위치를 사용하지 않을 것임을 Go에 알려야 합니다. 따라서 다음과 같이 참조를 포함하도록 go.mod 파일을 수동으로 수정해야 합니다.

module helloworld

go 1.14

require github.com/myuser/calculator v0.0.0

replace github.com/myuser/calculator => ../calculator

replace 키워드는 모듈의 원격 위치 대신 로컬 디렉터리를 사용하도록 지정합니다. 이 경우 helloworldcalculator 프로그램이 $GOPATH/src에 있으므로 위치는 단순히 ../calculator입니다. 모듈의 소스가 다른 위치에 있는 경우 여기에서 로컬 경로를 정의합니다.

다음 명령을 사용하여 프로그램을 실행합니다.

go run main.go

출력은 다음과 같습니다.

8
Version:  1.0

과제 1

주 애플리케이션의 calculator 패키지에서 logMessage 변수 또는 internalSum 함수를 호출하려고 하면 어떻게 되나요? 실행되나요? 한 번 시도해 보세요.

과제 솔루션:

package main

import (
 "fmt"
 "github.com/myuser/calculator"
)

func main() {
    total := calculator.internalSum(5)
    fmt.Println(total)
    fmt.Println("Version: ", calculator.logMessage)
}

패키지 게시

Go 패키지를 게시하는 것은 매우 쉽습니다. 패키지 소스 코드를 공개적으로 사용할 수 있도록 하기만 하면 됩니다. 대부분의 개발자는 GitHub를 사용하여 패키지를 공개적으로 사용할 수 있도록 하기 때문에 가져오기 문에서 github.com에 대한 참조를 찾을 수 있습니다.

예를 들어 calculator 패키지를 GitHub 계정에 게시하려면 calculator라는 리포지토리를 만들어야 합니다. URL은 다음과 유사합니다.

https://github.com/myuser/calculator

다음과 같이 리포지토리에 태그를 지정하여 패키지의 버전을 지정합니다.

git tag v0.1.0
git push origin v0.1.0

이 패키지를 사용하려는 개발자는(본인 포함) 다음과 같이 참조합니다.

import "github.com/myuser/calculator"

제3자 패키지를 참조하는 방법에 대해 자세히 살펴보겠습니다.

외부(타사) 패키지 참조

자신의 프로그램에서 다른 개발자가 작성한 패키지를 참조해야 하는 경우도 있습니다. 일반적으로 이러한 패키지는 GitHub에서 사용할 수 있습니다. 패키지(main이외의 패키지)를 개발하든 독립 실행형 프로그램(main 패키지)을 개발하든, 제3자 패키지 참조에 대한 다음 지침이 적용됩니다.

rsc.io/quote 패키지에 참조를 추가해 보겠습니다.

package main

import (
    "fmt"
    "github.com/myuser/calculator"
    "rsc.io/quote"
)

func main() {
    total := calculator.Sum(3, 5)
    fmt.Println(total)
    fmt.Println("Version: ", calculator.Version)
    fmt.Println(quote.Hello())
}

Visual Studio Code를 사용하는 경우 파일을 저장할 때 go.mod 파일이 업데이트됩니다. 이제 모양은 다음과 같습니다.

module helloworld

go 1.14

require (
    github.com/myuser/calculator v0.0.0
    rsc.io/quote v1.5.2
)

replace github.com/myuser/calculator => ../calculator

rsc.io/quote가 어떻게 패키지의 특정 버전을 참조하는지 확인하세요. 프로그램의 종속성을 업그레이드해야 하는 경우 여기에서 버전을 변경해야 합니다.

다음 명령을 사용하여 프로그램을 다시 실행합니다.

go run main.go

출력은 다음과 같습니다.

8
Version:  1.0
Hello, world.

제3자 패키지에 대한 이후의 모든 참조는 go.mod 파일에 있어야 합니다. 애플리케이션을 실행하거나 컴파일할 때 Go는 모든 종속성을 다운로드합니다.