🐞 Common Bug: Closure Captures a Variable from the Outer Scope
🔍 What’s a Closure?
A closure is a function that captures variables from the surrounding scope. In Go, when you define an anonymous function (like in a goroutine) that uses a variable from outside, it’s not copying the variable — it’s referencing it directly.
Using the goroutine function without sending a variable as a parameter could cause bugs in the application.
go
go func(ct context.Context) { t.sample(ct, *book)}(ctx)❌ The Problem: Closure over Book
To fix the “book” Variables in your goroutine, they must be correctly captured and not shadowed or unexpectedly shared due to closures.
Here’s the common issue:
- The “book” is being accessed inside the goroutine, but it was likely declared outside and may change before the goroutine runs (due to how closures work in Go).
- This can cause a race condition or unexpected “book” values inside the goroutine.

✅ Correct Approach: Capture the Variable Properly
Instead of relying on the closure capturing the variable, you can pass it explicitly as a parameter:
go
go func(ct context.Context, book Book) { t.sample(ct, book)}(ctx, *book)✅ Explanation:
- Ensures the current value “book” is preserved.
- Now the goroutine gets its copy of the
bookvalue at the time the goroutine is created. - The goroutine function takes a “book” parameter, making it safe and deterministic.
- This eliminates the closure over the
bookvariable from the outer scope. - This pattern is safe, deterministic, and avoids the potential race conditions or incorrect values.
