🔥 함수 클로저

341자
4분

Go 언어에서는 함수가 클로저(closure)가 될 수 있어요. 클로저는 자신의 몸체 외부에서 참조하는 변수를 가질 수 있는 함수 값이에요. 함수는 참조된 변수에 접근하고 값을 할당할 수 있어요. 이런 의미에서 함수는 변수에 "바인딩"되어 있다고 할 수 있죠.

예를 들어, adder 함수는 클로저를 반환해요. 반환된 각 클로저는 자신만의 sum 변수에 바인딩되어 있어요.

go
package main
 
import "fmt"
 
func adder() func(int) int {
	sum := 0
	return func(x int) int {
		sum += x // 외부 변수 sum을 캡쳐하여 사용
		return sum
	}
}
 
func main() {
	pos, neg := adder(), adder() // adder 함수를 호출하여 두 개의 클로저 생성
	for i := 0; i < 10; i++ {
		fmt.Println(
			pos(i),    // 첫 번째 클로저 호출, 양수 값을 더함
			neg(-2*i), // 두 번째 클로저 호출, 음수 값을 더함
		)
	}
}
 
go
package main
 
import "fmt"
 
func adder() func(int) int {
	sum := 0
	return func(x int) int {
		sum += x // 외부 변수 sum을 캡쳐하여 사용
		return sum
	}
}
 
func main() {
	pos, neg := adder(), adder() // adder 함수를 호출하여 두 개의 클로저 생성
	for i := 0; i < 10; i++ {
		fmt.Println(
			pos(i),    // 첫 번째 클로저 호출, 양수 값을 더함
			neg(-2*i), // 두 번째 클로저 호출, 음수 값을 더함
		)
	}
}
 

위 예제에서 adder 함수는 sum 변수를 캡쳐하는 클로저를 반환해요. 반환된 클로저는 sum 변수에 접근하고 값을 변경할 수 있어요.

main 함수에서 adder 함수를 두 번 호출하여 posneg 클로저를 생성해요. 각 클로저는 자신만의 sum 변수를 가지고 있어요.

for 루프에서 pos 클로저에는 양수 값을, neg 클로저에는 음수 값을 전달하며 호출해요. 각 클로저는 전달받은 값을 자신의 sum 변수에 누적해요.

실행 결과는 다음과 같아요:

text
0 0
1 -2
3 -6
6 -12
10 -20
15 -30
21 -42
28 -56
36 -72
45 -90
text
0 0
1 -2
3 -6
6 -12
10 -20
15 -30
21 -42
28 -56
36 -72
45 -90

pos 클로저는 0부터 45까지 양수 값을 누적하고, neg 클로저는 0부터 -90까지 음수 값을 누적하는 걸 볼 수 있어요.

이처럼 클로저는 외부 변수를 캡쳐하여 상태를 유지할 수 있어요. 이를 통해 함수형 프로그래밍의 강력한 기능을 구현할 수 있죠.

클로저는 Go 언어에서 함수를 일급 객체로 다룰 수 있게 해주는 중요한 개념이에요. 함수를 변수에 할당하거나 다른 함수의 인자로 전달할 수 있고, 함수 내에서 함수를 정의하고 반환할 수도 있죠. 이를 통해 코드의 모듈화와 추상화를 높일 수 있어요.

클로저를 사용할 때는 캡쳐된 변수의 라이프사이클과 메모리 관리에 주의해야 해요. 클로저가 외부 변수를 계속 참조하고 있다면 해당 변수는 가비지 컬렉션의 대상이 되지 않아요. 따라서 클로저를 적절히 관리하고 사용하는 것이 중요해요.

클로저는 함수형 프로그래밍, 콜백 함수, 지연 실행 등 다양한 시나리오에서 유용하게 사용될 수 있어요. Go 언어에서 클로저를 잘 활용하면 더 유연하고 표현력 있는 코드를 작성할 수 있답니다!

YouTube 영상

채널 보기
API 응답 지연과 복잡한 에러, NestJS 인터셉터로 관리하는 방법 | NestJS 가이드
변환 파이프로 컨트롤러 코드 깔끔하게 만들기 | NestJS 가이드
미들웨어 vs 가드, 왜 NestJS에서는 가드가 더 똑똑할까? | NestJS 가이드
매번 ValidationPipe 복붙하세요? NestJS 전역 파이프로 한 번에 해결하기 | NestJS 가이드
NestJS 커스텀 데코레이터, createParamDecorator 사용 | NestJS 가이드
입력을 전처리하는 Functor - Contravariant와 contramap 이해하기 | 프로그래머를 위한 카테고리 이론
C++ 속의 펑터 | 프로그래머를 위한 카테고리 이론
NestJS 역할 기반 접근 권한 부여 - Guard, Reflector | NestJS 가이드