Golang 에서는 JavaScript에 있는 클로저의 기능이 존재합니다.
우선 클로저에 대해 설명하자면....
클로저는 함수가 종료되도 함수 안에 있는 변수가 사라지지 않고, 계속 존재하며 사용할 수 있도록
해주는 것이 클로저입니다.
이렇게 읽어보면 정말 쓸대없고, 왜 사용하는지, 왜 존재하는지 이유를 모릅니다.
천천히 설명해보겠습니다.
1. Golang Closure
package main
func closure() func() {
var i int = 0
return func() {
i++
println(i)
}
}
func main() {
next := closure()
next()
next()
next()
}
//output :
1
2
3
클로저는 기본적으로 일급함수(람다함수)랑 같이 사용됩니다.
원형 함수를 변수에 넣고, 이를 실행 하므로서 return 되는 함수가 실행되는 형태가 되죠.
여기서 중요한점은 closure 라는 함수에서 변수 i 값이 사라지지않고 계속 존재한다는 것입니다.
이를 디버깅을 통해 확인하면 다음과 같이 됩니다.
$ go build -gcflags '-m' closure2.go
# command-line-arguments
.\closure2.go:5:9: can inline closure.func1
.\closure2.go:4:6: moved to heap: i
.\closure2.go:5:9: func literal escapes to heap
closure라는 함수는 컴파일러에 의해 인라인화 됩니다.
그 후 i 라는 값은 stack에서 heap으로 옮겨가는걸 확인할 수 있습니다.
또한 일급함수(람다함수)도 힙으로 옮겨가는걸 알 수 있죠.
다시말해서 golang에서 return으로 함수를 반환 받으면서, 해당 반환된 함수가 본채에 있는 함수의 변수를 가져다 사용하게 되면, 해당 함수는 closure로 바뀌게 되면서 컴파일러가 알아서 메모리 할당을 해준다는 뜻입니다.
이렇게 되므로서의 이점은 다음과 같습니다.
1. 함수가 inline화 되어 코드 최적화가 일어난다.
2 사용하는 변수는 closure 형태로 바뀌면서 stack -> heap으로 이동하게 된다.
2. Closure 사용 이유
Closure의 사용이유는 다음과 같습니다.
1. 함수의 캡슐화
2. 불필요한 전역변수를 없애고, 변수를 공유할 수 있게 된다.
함수의 캡슐화 부분은 해당 return 되는 함수에 직접접근할 수 없고, 본문 함수로 부터 return된 값을 받아오기 때문에,
OOP의 get(), set()과 동일한 움직임을 볼 수 있습니다.
불필요한 전역변수를 없애ㅗ, 변수를 공유할 수 있게 된다. 부분은 말 그대로 입니다.
예를들어 함수를 여러번 호출했을 때의 count 값을 얻고 싶거나, 함수를 호출하는 과정에서 값이 유지되어야 하는경우,
전역변수대신 closure를 사용하므로서 이를 해결할 수 있습니다.
그리고 이를 Capture 라고 부르는데, 마치 변수를 캡처해 보관하는것과 같다는 뜻으로 사용됩니다.
'프로그래밍 > Go언어' 카테고리의 다른 글
Golang interface에 대한 설명.... (0) | 2021.06.06 |
---|---|
Golang의 fmt.Print는 heap으로 간다? (0) | 2021.05.23 |
Golang 함수, 익명함수 사용법. (0) | 2021.05.16 |
Golang for문 사용법!! (0) | 2021.05.16 |
Golang 구조체 설명 (0) | 2021.05.02 |
댓글