1 분 소요

Golang Closure 활용

Closure stack, heap 구분

package main

func closure() func() {
	var i int = 0

	return func() {
		i++
		println(i)
	}
}

func main() {
	next := closure()

	next()
	next()
	next()
}

Closure stack, heap 확인

snoopy_kr@iMac Closure % go build -gcflags '-m' main.go
# command-line-arguments
./main3.go:3:6: can inline closure
./main3.go:6:9: can inline closure.func1
./main3.go:13:17: inlining call to closure
./main3.go:6:9: can inline main.closure.func1
./main3.go:15:6: inlining call to main.closure.func1
./main3.go:16:6: inlining call to main.closure.func1
./main3.go:17:6: inlining call to main.closure.func1
./main3.go:4:6: moved to heap: i
./main3.go:6:9: func literal escapes to heap
./main3.go:13:17: func literal does not escape

’./main3.go:4:6: moved to heap: i’ 에서 stack에서 heap으로 이동을 확인할 수 있다.

Simple Closure

package main

import "fmt"

func main() {
	a, b := 3, 4

	f := func(x int) int {
		return a*x + b
	}

	y := f(3)
	fmt.Println(y)
}

Closure 활용

package main

import "fmt"

// 베이스, 파리미터 없음
func nextValue() func() int {
	i := 0
	return func() int {
		i++
		return i
	}
}

// 베이스 추가, 파라미터 없음
func test1(i int) func() int {
	sum := i
	return func() int {
		sum = sum + i
		return sum
	}
}

// 베이스 추가, 파라미터 추가
func test2(seed int) func(i int) int {
	sum := seed
	return func(i int) int {
		sum = sum + i
		return sum
	}
}

func main() {
	a := test1(4)
	fmt.Println(a)   // 0x10a7640 포인트...
	fmt.Println(a()) // 8
	fmt.Println(a()) // 12

	b := test2(3)
	fmt.Println(b(5)) // 8
	fmt.Println(b(8)) // 16

	next := nextValue()

	fmt.Println(next()) // 1
	fmt.Println(next()) // 2
	fmt.Println(next()) // 3

	anotherNext := nextValue()

	fmt.Println(anotherNext()) // 1
	fmt.Println(anotherNext()) // 2

	fmt.Println(next()) // 4
}

댓글남기기