Package

chris·2023년 1월 16일
0

golang

목록 보기
3/8
post-thumbnail

Go 언어에서 모든 것은 package 형태로 제공한다. Go 언어에서 Package란 Go 언어로 작성된 소스 파일로, pakckage keyword 뒤에 package 이름을 적은 문장으로 시작한다.
Package는 주로 서로 관련된 함수나 변수나 상수끼리 그룹으로 묶는 데 활용한다. 이렇게 하면 다른 곳으로 전달하기도 쉽고 자신이 작성한 다른 프로그램에서 활용하기도 편리하다.
main package를 제외한 다른 모든 Go package는 독립적인 프로그램이 아니어서 실행 파일 형태로 컴파일할 수 없다.
Go에 사용하는 표준패키지는 https://golang.org/pkg 에 자세히 설명되어 있다. Go 프로그래밍에서 표준패키지를 자주 불러 사용하므로 이 링크를 자주 참조하게 될 것이다.

Go package 만들기

Go pcakge를 구성하는 소스 코드는 모두 package 이름과 같은 이름의 directory 안에 담으며, 각각의 코드를 서로 다른 하위 directory에 담을 수 있다. 단, main package는 예외적으로 아무데나 둘 수 있다.

인증 관련 package를 만들어보자.

  1. project 생성
$ mkdir go-package
$ cd go-package
$ go mod init github.com/chris-han-nih
  1. package 생성
    package내의 함수, 인터페이스, 구조체 등의 이름 첫 문자를 대문자로 시작하면 public으로 사용할 수 있다.
package auth

import (
	"fmt"
)

func Token() {
	fmt.Println("Token")
}
  1. package 사용
package main

import "github.com/chris-han-nih/auth"

func main() {
	auth.Token()
}

init 함수

Go package는 옵션으로 init()이란 함수를 가질 수 있다. 이 함수는 package를 시작할 때 자동으로 호출된다.
init() 함수는 근본적으로 private 함수다. 따라서 이 패키지를 불러온 코드가 아닌, package 외부에서 호출할 수 없다. 또한 package 사용자는 init() 함수를 마음대로 제어할 수 없다.

init() 함수는 언제 사용하면 좋을까?

다음과 같이 package 사용전 초기화 되어야 할 경우 사용한다.

// account package

package account

var Groups map[string]string

func init() {
	Groups := make(map[string]string)
}
// main package

package main

import (
	"account"
)

func main() {
	account["key"] = "value"
    // 만약 init 함수에서 초기화를 하지 않았다면 다음과 같은 오류가 발생
    // panic: assignment to entry in nil map
}

alias

  1. package의 init() 함수만 필요할 경우
import (
	"database/sql"

	_ "github.com/lib/pq"
)
  1. 같은 이름의 package를 1개 이상 import 해야 할 경우
import (
	"strings"
    chris "strings"
)
  1. 기타
import (
	. "math"
)

func main() {
	fmt.Println(Abs(-1))
}

Go package 잘 만드는 방법

  • Package의 구성 요소들이 어떤 식으로든 서로 관련이 있어야 한다.
  • 특별한 이유가 없다면 package에서 함수를 너무 많이 제공하지 않는다. Package에서 제공하는 함수의 수가 적어야 이해하기도 쉽고 사용하기도 쉽다.
  • 함수의 이름만 봐도 기능을 알 수 있도록 표현하되 너무 긴 이름은 피한다.
  • Interface를 화룡ㅇ하면 함수의 활용도를 높일 수 있다. 따라서 적적하다고 판단되면 함수의 매개변수나 리턴 타입을 한 가지 타입으로 지정하지 말고 인터페이스로 정의한다.
  • Package를 업데이트할 때 꼭 피요한 경우가 아니라면 기존 버전과 크게 달라지거나 충돌이 발생하지 않게 한다.
  • Go package를 새로 만들 때, 비슷한 태스크나 개념을 하나로 묶을 수 있도록 여러 개의 파일로 나눠서 작성한다.
  • 표준 라이브러리에 적용된 규칙에 따라 package를 작성한다. 표준 라이브러리에 속한 Go package의 코드를 읽어보면 도움된다.
  • Log 정보를 화면에 출력하는 package를 좋아할 사람은 없다. 굳이 필요하다면 Log 출력 기능을 옵션으로 제공하는 것이 보다 좋은 방법이다.
  • 새로운 타입 정의는 이를 처음 사용하는 곳에 가까이 두면 편하다. 그 타입의 정의를 찾기 위해 소스 코드를 뒤지는 것을 좋아할 사람은 없다.
  • 특별한 장점이 없는 package를 만들지 않는다. 그 시간에 차라리 다른 일을 하는 게 낫다.
profile
software engineer

0개의 댓글