golang closure

Look! there's a flower!·2024년 12월 23일

golang closure

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에서 변환 할 필요시 사용하면 유용함

profile
Why don't you take a look around for a moment?

0개의 댓글