TGPL: Capturing Iteration Variables

54 阅读1分钟

Consider a program that must create a set of directories and later remove them. We can use a slice of function values to hold the clean-up operations.

var rmdirs []func()
for _, d := range tempDirs() {
    dir := d
    os.MkdirAll(dir, 0755)
    rmdirs = append(rmdirs, func(){
        os.RemoveAll(dir)
    })
}

// ...do some work
for _, rmdir := rmdirs() {
    rmdir()
}

You may be wondering why we assigned the loop variable d to a new local variable dir within the loop body, instead of just naming the loop variable dir as in this subtly incorrect variant:

var rmdirs []func()
for _, dir := range tempDirs() {
    os.MkdirAll(dir, 0755)
    rmdirs = append(rmdirs, func(){
        os.RemoveAll(dir)
    })
}

Because in for loop, dir use same address but change its value in each loop, so in an answer stackoverflow.com/questions/5…

the value of dir will hold the last value, so use a temp variable to storage the loop value is necessary.