如何推迟函数返回的匿名函数

Let’s say you have a function that sets up your application server and returns a function that should be run right before your application exits.

func main() {
  defer applicationExit()
}

func applicationExit() func() {
  fmt.Println(" Application Setup Call")

  return func() {
    fmt.Println("Application Tear Down Call")
  }
} 

You will get the following output. Output: Application Setup Call

What went wrong? Why don’t we see the output Application Tear Down Call

You have to invoke the function that is returned. applicationExit() just returns the function and does nothing else. To execute it you have to invoke the function.

func main() {
  defer applicationExit()()
}

func applicationExit() func() {
  fmt.Println(" Application Setup Call")

  return func() {
    fmt.Println("Application Tear Down Call")
  }
} 

Your code does exactly what is expected:

func main() {
    defer applicationExit()
}

Translated to English, this code means:

  • Wait until main exits, then call applicationExit().

This is what happens. But what you seem to want is, instead:

  • Execute applicationExit() immediately, and store the return value for later.
  • Wait until application exits, then call the anonymous function returned by applicationExit().

If we write this actual code, we get something like:

func main() {
    cleanup := applicationExit() // Call applicationExit() immediately
    defer cleanup() // Wait until main() exits, then call cleanup()
}

which can be shortened to:

func main() {
    defer applicationExit()()
}