PHpullh
학습 라이브러리/Go/클로저 & 함수 타입

GO · 함수

클로저 & 함수 타입

Go의 클로저로 상태를 캡슐화하고, 함수를 일급 값으로 활용합니다.

함수중급closure클로저first-classmiddlewarepipeline

핵심 설명

Go의 클로저로 상태를 캡슐화하고, 함수를 일급 값으로 활용합니다.

Go code

package main

import "fmt"

// 클로저 — 외부 변수 캡처
func makeCounter(start int) func() int {
	count := start
	return func() int {
		count++
		return count
	}
}

// 클로저로 미들웨어 패턴
type Handler func(string) string

func withLogging(h Handler) Handler {
	return func(req string) string {
		fmt.Printf("[LOG] 요청: %s
", req)
		resp := h(req)
		fmt.Printf("[LOG] 응답: %s
", resp)
		return resp
	}
}

func withAuth(h Handler) Handler {
	return func(req string) string {
		if req == "" {
			return "401 Unauthorized"
		}
		return h(req)
	}
}

// 함수 슬라이스
func pipeline(fns ...func(int) int) func(int) int {
	return func(x int) int {
		for _, fn := range fns {
			x = fn(x)
		}
		return x
	}
}

func main() {
	// 카운터 클로저
	c1 := makeCounter(0)
	c2 := makeCounter(10)
	fmt.Println(c1(), c1(), c1()) // 1 2 3
	fmt.Println(c2(), c2())       // 11 12 (독립적)

	// 미들웨어 체이닝
	handler := func(req string) string {
		return "200 OK: " + req
	}
	wrapped := withLogging(withAuth(handler))
	fmt.Println(wrapped("GET /api/users"))
	fmt.Println(wrapped(""))

	// 파이프라인
	double  := func(n int) int { return n * 2 }
	addOne  := func(n int) int { return n + 1 }
	square  := func(n int) int { return n * n }

	pipe := pipeline(double, addOne, square)
	fmt.Println(pipe(3)) // (3*2+1)^2 = 49
}

학습 팁

Go 클로저는 변수를 참조로 캡처합니다. 고루틴과 클로저를 함께 쓸 때는 루프 변수를 별도 변수에 복사하세요.

주의할 점

루프에서 고루틴 + 클로저 사용 시 클래식 버그: for i := range s { go func() { fmt.Println(i) }() }는 모두 같은 i를 출력합니다.

자주 묻는 질문

클로저 & 함수 타입란 무엇인가요?

Go의 클로저로 상태를 캡슐화하고, 함수를 일급 값으로 활용합니다.

클로저 & 함수 타입 학습 시 주의할 점은 무엇인가요?

루프에서 고루틴 + 클로저 사용 시 클래식 버그: for i := range s { go func() { fmt.Println(i) }() } 는 모두 같은 i 를 출력합니다.