The following Go code demonstrates a distinction in the closure-capture rules between defer and go closures. In a tutorial, I was told that for-loop variables have scope limited to the loop body, but something seems different here.
package main
import "fmt"
func deferred() {
for i := 0; i < 5; i++ {
defer fmt.Println(i)
}
}
func cps() {
clo := new(func())
*clo = func() {}
defer func() { (*clo)() }()
for i := 0; i < 5; i++ {
oldClo := *clo
*clo = func() {
fmt.Println(i)
oldClo()
}
}
}
func cpsCpy() {
clo := new(func())
*clo = func() {}
defer func() { (*clo)() }()
for i := 0; i < 5; i++ {
oldClo := *clo
cpy := i
*clo = func() {
fmt.Println(cpy)
oldClo()
}
}
}
func main() {
fmt.Println("defer")
deferred()
fmt.Println("cps")
cps()
fmt.Println("cpsCpy")
cpsCpy()
}
This produces output:
defer
4
3
2
1
0
cps
5
5
5
5
5
cpsCpy
4
3
2
1
0
If the difference is intentional, then what are the different use-cases that justify it?