Local Helper Closure
Local Helper Function
- A technique of assigning an anonymous function that is only used inside a function to a variable.
- Minimizes argument passing by capturing variables from the parent function and removes repetitive logic.
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}
Advantages
- Can eliminate duplicate code
- Simplified Function Arguments
- Uses captured external variables instead of function arguments (closure)
- Share state without global variables
- Shares local variables within the scope
- Encapsulation/Isolation
- Usable only within its scope
Caution
- Cannot write unit tests
- From a functional programming perspective, it's an impure function
- Avoid capturing too many external variables
- It's best to keep it short for readability
- Loop Variable Capture Issue
- Go 1.21 and below: The loop variable (
v) is not newly created with each iteration; instead, it continuously overwrites a single memory address- Go 1.22 and above: A new variable is created (shadowing) for each iteration of the loop