function 안에서 variable을 선언하고 그 내부에서 inner function을 선언했을 때 그 inner function 안에서 외부 변수를 사용할 수 있는데 이것을 closure 라고 함
샘플1:
func counter() func() int {
count := 0 // Closure variable
return func() int {
count++ // Modifies the outer variable
return count // Accesses the modified variable
}
}
func main() {
c := counter() // Create a closure
fmt.Println(c()) // Output: 1
fmt.Println(c()) // Output: 2
fmt.Println(c()) // Output: 3
}
샘플2:
func adder(base int) (func(int) int, func(int) int) {
sum := base
add := func(x int) int {
sum += x
return sum
}
subtract := func(x int) int {
sum -= x
return sum
}
return add, subtract
}
func main() {
add, subtract := adder(10) // Shared closure variable `sum`
fmt.Println(add(5)) // Output: 15
fmt.Println(subtract(3)) // Output: 12
fmt.Println(add(2)) // Output: 14
}
일전에 c++ 코드를 golang으로 포팅할 때 static variable 때문에 고생한적이 있었음
함수 안에서 static variable을 사용한 C++ 코드를 golang으로 변환할 때
결국은 global 변수를 써서 해결했는데 이때 중간 계산을 위해서 많은 static variable을 쓰는 경우가 있었는데 변수 이름도 i, j, a, b, c 등 단순한 변수명을 static 변수를 썼음
당시 내가 생각할 수 있었던 유일한 방법은 struct 를 하나 선언하고 그 안에 static 변수들에 해당하는 변수들을 선언하고 global variable로 함수 마다 하나씩 선언해준 후 그 함수 안에서는 global variable을 액세스해서 썼음.
그런 경우, 원래 코드에서는 if (a > b) c = ... 와 같은 단순한 코드라도 if (g_A.a > g_A.b) g_A.c = ... 와 같은 식으로 사용할수 밖에 없었는데 이때 단순한 함수면 그래도 쉽게 변환할 수 있었는데 당시의 함수는 복잡하고 라인 수도 아주 많은 계산 함수라 중간에 변환에 집중하지 않으면 내가 오류를 만들어 아주 힘들었음.
그런 경우 closure를 이용하면 아주 손쉽게 해결할 수 있음
즉 위의 outer 함수에 static 에 해당하는 변수를 선언하고 내부 함수에서는 local variable만 선언하면 코드는 변경없이 거의 그대로 쓸수 있음
func myCounter() func() int {
count := 0 // Closure variable --- 여기서 static에 해당하는 변수 선언
return func() int {
count++ // Modifies the outer variable
return count // Accesses the modified variable
}
}
나중에 c++ static 변수 스타일을 golang에서 변환 할 필요시 사용하면 유용함