Golang Closure

Golang Closure

Golang의 Closure 기법을 분석한다.

1. Golang Closure

Golang에서도 Javascript와 동일하게 Closure 기능을 제공한다. Closure는 함수를 객체화하여 함수가 상태를 갖게하는 기법을 의미한다.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package main

import (
    "fmt"
)

func nextFunc(i int) func() int {
	j := 0
	return func() int {
		j++
		return i + j
	}
}

func main() {
	next10 := nextFunc(10)
	fmt.Println(next10()) // 11
	fmt.Println(next10()) // 12
	fmt.Println(next10()) // 13

	next20 := nextFunc(20)
	fmt.Println(next20()) // 21
	fmt.Println(next20()) // 22
	fmt.Println(next20()) // 23
}
[Code 1] Golang Closure

[Code 1]은 Golang의 Closure 예제를 나타내고 있다. nextFunc() 함수는 자신이 넘겨받은 i Parameter와 1씩 계속 증가하는 j 지역변수를 더하는 함수를 반환한다. Closure를 지원하지 않는 일반적인 언어에서는 동작할 수 없는 함수이다. Stack에 저장되는 i Parameter와 j 지역변수는 nextFunc() 함수가 종료되는 순간 해제되기 때문에 nextFunc() 함수가 반환하는 함수에서는 이용할 수 없기 때문이다.

하지만 Golang에서는 Closure를 지원하기 때문에 nextFunc() 함수의 종료와 함께 Closure가 구성되고, i Paramter와 j 지역변수는 구성된 Closure에 저장된다. 여기서 Closure가 구성된다는 의미는 Stack에 저장되어 변수들을 Heap에 복사하여 저장하고 관리된다는 의미를 뜻한다. 따라서 i Parameter와 j 지역변수도 Heap에 저장된다. 따라서 nextFunc() 함수가 반환한 함수는 Clousre에 저장된 변수들을 통해서 동작하게 된다.

[Code 1]에서 next10, next20 변수는 함수 nextFunc()에 의해서 반환되는 함수를 각각 저장하고 있으며, 따라서 각각 별도의 Closure가 구성된다. 이후에 각 Clouser에 저장되어 있는 변수를 활용하여 동작한다. next10 변수의 Closure에는 j = 0, i = 10 값이 저장되어 있다. next10 변수를 호출 할 때마다 j의 값이 증가하기 때문에 11, 12, 13 값이 출력된다. next20 변수의 Closure에는 j = 0, i = 20 값이 저장되어 있다. next20 변수를 호출 할 때마다 j의 값이 증가하기 때문에 21, 22, 23 값이 출력된다.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
package main

import "fmt"

func arryFunc() func() []int {
	arry := []int{1, 2, 3, 4, 5}
	return func() []int {
		return arry
	}
}

func main() {
	arry := arryFunc()
	fmt.Println(arry()) // 1,2,3,4,5
}
[Code 2] Golang Closure to Replace Global Variables

[Code 2]는 Closure를 활용하여 Global 변수를 대체하는 방법을 나타내고 있다. 변수를 Closure에 저장하는 방식을 활용하면 Global Variable의 사용을 줄일 수 있다. [Code 2]에서는 arrayFunc() 함수의 Closure에 Integer Slice를 할당하고 이용하는 예제를 나타내고 있다.

2. 참조