한 번에 묶어 정리하려다가 function 이것저것 할 말이 많아서 따로 정리한다ㅏ.
Function
go에서 함수는 func 키워드를 사용하여 정리한다.
호출되는 함수가 반드시 호출하는 함수의 앞에서 정의되어야 할 필요는 없다.
포인터가 있는 곳에 reference가 있는 법
Go에서도 함수에 인자를 전달하는 방법이 Pass by Value와 Pass by Ref 로 나뉜다.
늘 그렇듯이 Pass By Value는 인자의 값을 복사하여 함수에 전달하고,
Pass By Reference는 인자가 저장된 주소값을 가져와서 dereference하여 사용한다.
다른 언어에선 모르겠지만, C++과 확연하게 다른 점이 함수파트에서 극명하게 드러난다.
Variadic Function (가변인자함수)
함수에 정해진 수의 인자가 아닌 N개 (N은 0이상의 정수) 의 인자를 전달하고 싶을 때가 있다.
이럴 때 Go에서는 ellipsis를 통해 그것을 가능케 한다. 아 이거 진짜 짱인듯.
package main
func main() {
say("This", "is", "a", "book")
say("Hi")
}
func say(msg ...string) {
for _, s := range msg {
println(s)
}
}
If the last parameter of a function has type ...T, it can be called with any number of trailing arguments of type T.
The actual type of ...T inside the function is []T.
그러니까 결국 마지막 param의 type앞에 ...이 붙으면 N(N>=0)개의 인자가 들어갈 수 있다.
혹시 여러개의 type도 되나하고 func (...int, ...string) 해봤는데 안됐다. 낄낄....
그런데 이 문제 역시 후에 나올 interface를 통해 ...interface{}를 인자의 type으로 적용함으로 해결할 수 있다.
그럼 이제 함수의 return 값은 어떻게 지정해주는지 알아보자.
함수에서 return값이 있는 경우의 함수 형태는 다음과 같다.
func <func name>param1 <param type>, ...param2 <param type>) <return type> {
}
복수개의 값을 리턴할 수도 있다.
package main
func main() {
count, total := sum(1, 7, 3, 5, 9)
println(count, total)
}
func sum(nums ...int) (int, int) {
s := 0 // 합계
count := 0 // 요소 갯수
for _, n := range nums {
s += n
count++
}
return count, s
}
값 여러개 return할 수 있는 거 진짜 좋은 것 같다!
C++ 진짜 무조건 하나로 자료형 만들어서 리턴타입 지정해줘야 하는 거 진짜 짜증났는데 아주 굳
근데 함수 사용할 때 함수의 return type에 따라 그 수만큼 변수만들어서 값 가져와야 한다는 것 까먹지 말자.
특이하게 return variable를 미리 지정해 놓을 수도 있다.
Named Return Parameter라는 것인데 다음과 같은식으로 쓸 수 있다.
func sum(nums ...int) (count int, total int) {
for _, n := range nums {
total += n
}
count = len(nums)
return
}
return할 변수는 count와 total로 정해져있다.
return statement가 어떠한 argument를 가지지 않고 named return value를 리턴하는데, 이를 "naked" return이라고 한다.
(근데 실제 return문에서 아무것도 리턴하진 않지만, 어쨌든 함수가 끝나면 반환되는 값은 있기 때문에 return을 어딘가는 꼭 써줘야 함. 당연한 것 같지만 나는 까먹을 수도 있을듯ㅋㅋ)
이거 readability를 해치기 때문에 긴 함수에선 쓰지 않고 짧은 함수에서만 사용해야한다는데, 굳이 왜 만들었나 싶다.
뭐 PS할 때는 편할 수도 있을 것 같다...
Go에서의 함수에 대해 조금 정리하고 다음으로 넘어가고 싶다.
Go에서 함수는 first-class 이다. 쉽게는 함수를 변수처럼 사용할 수 있다고 이해하면 되겠다.
우리는 변수를 사용할 때
- 새로운 변수에 그 값을 담을 수 있다.
- 함수의 param / return 값이 될 수 있다.
- 새로운 type으로 지정할 수 있다.
완벽한 정의는 아니지만.. 일단 이걸 짚고 넘어가면 다음에 나올 것들이 조금 이해하기 쉽다.
Anonymous Function
익명함수란, 함수명을 갖지 않는 함수를 말한다. function literal 이라고도 한다.
보통 함수 전체가 변수에 할당되거나, 다른 함수의 parameter에 직접 정의되곤 한다.
package main
func main() {
sum := func(n ...int) int { //익명함수 정의
s := 0
for _, i := range n {
s += i
}
return s
}
result := sum(1, 2, 3, 4, 5) //익명함수 호출
println(result)
}
Functions as type
함수의 원형을 하나의 type으로 만들 수 있다.
이렇게 함수의 원형을 정의하고 함수를 타 메서드에 전달하고 리턴받는 기능을 타 언어에서 흔히 델리게이트(Delegate)라 부른다. Go는 이러한 Delegate 기능을 제공하고 있다.
// 원형 정의
type calculator func(int, int) int
// calculator 원형 사용
func calc(f calculator, a int, b int) int {
result := f(a, b)
return result
}
하나하나 자세히 보면 어려운 건 없다.
하지만 지금 확실하게 정리 안 하면 나중에 코드 짜다가 나 혼자 머리가 터져버릴거얌,,,
나는 functional programming 할 때도 이게 너무 어려웠다고!!
Closure
함수 바깥에 있는 변수를 참조하는 function value. 함수 밖의 변수를 함수 안에서 읽고 쓸 수 있다.
Go에서 함수는 Closure로 사용될 수 있다.
다음 예제를 일단 한 번 보자
package main
func nextValue() func() int {
i := 0
return func() int {
i++
return i
}
}
func main() {
next := nextValue()
println(next()) // 1
println(next()) // 2
println(next()) // 3
anotherNext := nextValue()
println(anotherNext()) // 1 다시 시작
println(anotherNext()) // 2
}
closure를 사용하면 지역 변수가 소멸되지 않고, 함수가 호출될 때마다 계속 그 변수를 사용할 수 있다.
함수가 선언될 때의 환경을 유지하여, 프로그램의 흐름을 변수에 저장할 수 있게한다.
뭐 이거 뭐할 때 쓰는지 잘 모르겠음... functional programming할 때도 했는데 그 때도 잘 이해 못했다;
쨌든 Go 또한 closure를 통해 함수형 프로그래밍을 가능케 하는 거겠지...? 맞겠지...?
+ go에서의 closure를 자세하게 설명한 사이트가 있길래 끌어와 본다.
closure 자체의 개념을 설명한 것은 아니고, go에서 어떻게 쓸 수 있는지의 예제들이 대부분이다.
보고나면 아아~~~~ 할 순 있는데 그래도 아직 완벽하게 이해한 건 아닌 것 같다ㅜ
https://www.calhoun.io/5-useful-ways-to-use-closures-in-go/
Calhoun.io - Go for Everyone
...
www.calhoun.io
ㅠㅜ 대충 정리하긴 했는데 언제나 그렇듯 뭔가 중요한 건 빠진 느낌...
피드백 언제나 환영합니다!
제가 잘못 이해한 것이 있다면 언제든지 댓글로 알려주세요 ㅎㅎ
출처 : http://golang.site/
예제로 배우는 Go 프로그래밍
쉽고 재미있는 Go 프로그래밍 예제로 배우는 Go 프로그래밍 I like a lot of the design decisions they made in the [Go] language. Basically, I like all of them. - Martin Odersky, Creator of Scala
golang.site
'CS > Go' 카테고리의 다른 글
| Go Lang - Package ~ Interface (580) | 2020.05.05 |
|---|---|
| Go Lang - 기초 문법 정리 (238) | 2020.05.04 |