Home  >  Article  >  Backend Development  >  Why Does Deferring Closure Capture in Go Lead to Unexpected Behavior?

Why Does Deferring Closure Capture in Go Lead to Unexpected Behavior?

Linda Hamilton
Linda HamiltonOriginal
2024-11-10 19:35:02473browse

Why Does Deferring Closure Capture in Go Lead to Unexpected Behavior?

Deferring Closure Capture in Go

Go's defer statement can be used to execute a function after the surrounding function returns. However, when used with closures, it's important to understand how parameter capture works.

The Issue

Consider the following code:

package main

import "fmt"

func main() {
    var whatever [5]struct{}

    for i := range whatever {
        fmt.Println(i)
    } // part 1

    for i := range whatever {
        defer func() { fmt.Println(i) }()
    } // part 2

    for i := range whatever {
        defer func(n int) { fmt.Println(n) }(i)
    } // part 3
}

The output of the code is:

0
1
2
3
4
4
3
2
1
0
4
4
4
4
4

Analysis

  • Part 1: Prints the loop counter i as expected.
  • Part 2: Captures the variable i in the closure. However, when the closure executes, i has the value from the last iteration of the loop, which is 4. Hence, it prints "44444".
  • Part 3: Doesn't capture any outer variables. The closure is evaluated when the defer statement executes, so each defer call has a different value of n, resulting in "43210".

Key Differences

The crucial difference between parts 2 and 3 lies in whether or not the closure captures outer variables. In part 2, the closure captures i, which is a reference to an outer variable. In part 3, the closure doesn't have any outer references, so each call has a different value of n.

Additional Considerations

  • Defer calls are executed in last-in-first-out (LIFO) order before the surrounding function returns.
  • The expression evaluated when the defer statement executes, not the function itself.

The above is the detailed content of Why Does Deferring Closure Capture in Go Lead to Unexpected Behavior?. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn