Go Package
Go에서 모든 것은 패키지 형태로 제공된다. 패키지는 Go로 작성된 소스 파일로, package 키워드 뒤에 패키지 이름을 적은 문장으로 시작된다.
패키지는 주로 서로 관련된 함수나 변수나 상수끼리 그룹으로 묶는데 활용된다. 주의할 점은 main 패키지를 제외한 다른 모든 패키지는 독립적인 프로그램이 아니여서 실행 파일 형태로 컴파일할 수 없다.
익명 함수
익명 함수는 따로 이름을 붙이지 않고 코드 안에서 정의한다. Go에서 함수는 익명 함수를 리턴할 수도, 매개변수로 받을 수도 있다. 또한 익명 함수를 변수에 연결할 수 있다. 함수형 프로그래밍에서는 이러한 익명 하수를 클로저라고 부른다.
리턴값에 이름 붙이기
이름있는 리턴값으로 선언된 함수에서 return문에 아무런 인수도 지정하지 않으면, 각 네임드 리턴 값의 현재 값을 앞에서 선언된 순으로 리턴한다.
package main
import "fmt"
func namedMinMax(x, y int) (min, max int) {
if x > y {
min = y
max = x
} else {
min = x
max = y
}
return
}
func main() {
fmt.Println(namedMinMax(5, 2))
}
$ go run foo.go
2 5
포인터를 매개변수로 받는 함수
포인터를 매개변수로 받을 수 있도록 함수를 정의할 수 있다.
package main
import "fmt"
func getPtr(v *float64) float64 {
return *v * *v
}
func main() {
x := 12.2
fmt.Println(getPtr(&x))
x = 12
fmt.Println(getPtr(&x))
}
$ go run foo.go
148.83999999999997
144
포인터를 리턴하는 함수
포인터를 리턴하게 하면 프로그램의 구조가 간결해지고, 코드를 반복적으로 복사하 ㄹ필요 없이 핵심적인 일에 집중할 수 있다.
package main
import "fmt"
func returnPtr(x int) *int {
y := x * x
return &y
}
func main() {
sq := returnPtr(10)
fmt.Println("sq :", *sq)
}
$ go run foo.go
sq : 100
함수를 리턴하는 함수
package main
import "fmt"
func funReturnFun() func() int {
i := 0
return func() int {
i++
return i * i
}
}
func main() {
i := funReturnFun()
j := funReturnFun()
fmt.Println("1:", i())
fmt.Println("2:", i())
fmt.Println("j1:", j())
fmt.Println("j2:", j())
fmt.Println("3:", i())
}
$ go run foo.go
1: 1
2: 4
j1: 1
j2: 4
3: 9
실행 결과를 보면 두 변수 i, j는 완전히 독립적이라는 것을 확인할 수 있다.
함수를 매개변수를 받는 함수
package main
import "fmt"
func function1(i int) int {
return i + i
}
func function2(i int) int {
return i * i
}
func funFun(f func(int) int, v int) int {
return f(v)
}
func main() {
fmt.Println("function1:", funFun(function1, 123))
fmt.Println("function2:", funFun(function2, 123))
fmt.Println("inline:", funFun(func(i int) int {return i * i * i},123))
}
$ go run foo.go
function1: 246
function2: 15129
inline: 1860867
Go 패키지 직접 만들기
Go 패키지를 구성하는 소스 코드는 모두 패키지 이름과 같은 이름의 디렉토리 안에 담으며, 각각의 코드를 서로 다른 하위 디렉토리에 담을 수 있다. 단 main은 예외적으로 아무데나 둘 수 있다.
package aPackage
import "fmt"
func A() {
fmt.Println("This is function A")
}
func B() {
fmt.Println("This is function B")
}
const MyConstant = 123
const privateConstant = 21
package main
import (
"fmt"
"github.com/callistaenterprise/goblog/aPackage"
)
func main() {
aPackage.A()
aPackage.B()
fmt.Println(aPackage.MyConstant)
}
$ go run foo.go
This is function A
This is function B
123
Encapsulation
Go에서는 함수, 변수, 타입의 이름에서 첫 글자를 대문자로 지정하면 public이며, 소문자로 시작하면 private으로 지정된다.
init() 함수
Go 패키지는 옵션으로 init()이란 함수를 가질 수 있다. 이 함수는 패키지를 시작할 때 자동으로 호출된다.
Go 패키지 Tips
- 패키지 구성 요소들이 어떤 식으로든 서로 관련이 있어야 한다. 많은 기능을 넣는 것보다 차라리 쓸데 없을 정도로 패키지를 잘게 나누는 것이 낫다
- 패키지를 외부에 공개하기 전에 먼저 내부적으로 충분히 사용해봐야 한다.
- 패키지에서 함수를 너무 많이 제공하지 않는다.
- 인터페이스를 활용하자
'Go 언어 공부' 카테고리의 다른 글
[GO 마스터하기] 08-유닉스 시스템콜 (0) | 2020.09.21 |
---|---|
[GO 마스터하기] 07-리플렉션과 인터페이스 (0) | 2020.09.21 |
[GO 마스터하기] 05-Go 자료구조 (0) | 2020.09.16 |
[GO 마스터하기] 04-합성 타입 사용법 (0) | 2020.09.07 |
[GO 마스터하기] 03-Go언어의 기본 데이터 타입 (0) | 2020.09.07 |