Pattern) Local Helper Closure

Local Helper Closure

지역 헬퍼 함수

  • 함수 내부에서만 사용하는 익명 함수(Anonymous Function) 를 변수에 할당하여 사용하는 기법
  • 부모 함수의 변수를 캡처(Capture) 하여 인자 전달을 최소화하고, 반복되는 로직을 제거

e.g.

 1func BuildControllers(ctx context.Context, controllerCtx ControllerContext, controllerDescriptors map[string]*ControllerDescriptor,
 2	unsecuredMux *mux.PathRecorderMux, healthzHandler HealthCheckAdder) ([]Controller, error) {
 3	...
 4	buildController := func(controllerDesc *ControllerDescriptor) error {
 5		controllerName := controllerDesc.Name()
 6		ctrl, err := controllerDesc.BuildController(ctx, controllerCtx)
 7		...
 8		controllers = append(controllers, ctrl)
 9		checks = append(checks, check)
10		return nil
11	}
12	...
13	for _, controllerDesc := range controllerDescriptors {
14		...
15		if err := buildController(controllerDesc); err != nil {
16			return nil, err
17		}
18	}
19	...
20}
장점
  • 중복 코드 제거 가능
  • 함수 인자 단순화
    • 함수 인자 대신 외부 변수를 캡쳐해서 사용(클로저)
  • 전역 변수 없이 상태 공유
    • 스코프 내의 지역 변수들을 공유
  • 캡슐화/격리
    • 스코프 내에서만 사용 가능
주의
  • 단위 테스트 작성 불가
  • 함수형 프로그래밍 관점에서는 순수하지 않은(impure) 함수
  • 너무 많은 외부 변수 캡쳐는 지양
  • 가독성을 위해 짧게 유지하는 것이 좋음
  • Loop Variable Capture 이슈
    • Go 1.21 이하: 루프 변수(v)는 반복문이 돌 때마다 새로 생성되는 게 아니라, 하나의 메모리 주소를 계속 덮어씀
    • Go 1.22 이상: 루프의 각 반복(Iteration)마다 변수를 새로 생성(Shadowing)

포스트
카테고리
시리즈