Замыкание (closure) захватывает переменную по ссылке, а не по значению. Классическая ловушка — цикл с горутинами:
// Баг: все горутины выведут одно значение
for i := 0; i < 5; i++ {
go func() {
fmt.Println(i) // захватывает переменную i, не значение
}()
}
// Фикс 1: передать как аргумент
for i := 0; i < 5; i++ {
go func(n int) {
fmt.Println(n)
}(i)
}
С Go 1.22 переменная цикла for создаётся заново на каждой итерации, поэтому этот баг больше не возникает в новых версиях. Но для замыканий вне циклов правило всё ещё актуально.