[Golang] Anonymous Function in Defer Statement


TL;DR: Syntax for using anonymous function in Go defer statement

defer func() {
      // do something here after surrounding function returns
}()

Explanation

I want to execute c <- 1 right after surrounding function returns [1] [2]. In the beginning I thought it was easy to do this with defer, so I write the following code:

defer c <- 1

But the code cannot be compiled successfully. The compiler complained that expression in defer must be function call. So I searched and found this on A Tour of Go:

A defer statement defers the execution of a function until the surrounding function returns.

It looks like defer must be followed by a function, so I thought I can use anonymous function in this case. Then I tried again and wrote the following code:

defer func() { c <- 1 }

I still got the same complaint from compiler. After more searches, I found that the correct way to do this is:

defer func() { c <- 1 }()

The () means call and execute the anonymous function. If you write only func() { c <- 1 } without (), you only declare the anonymous function without calling it. That's why I got the same error while compiling.

The following are complete example for using anonymous function in defer statement.

Run Code on Go Playground

package main

import (
      "fmt"
)

func routine(site string, c chan int) {
      defer func() { c <- 1 }()

      // do something
      fmt.Println(site)
}

func main() {
      c := make(chan int)

      sites := []string{
              "https://www.google.com/",
              "https://duckduckgo.com/",
              "https://www.bing.com/"}

      for _, site := range sites {
              go routine(site, c)
      }

      // wait all goroutines to finish
      for i := 0; i < len(sites); i++ {
              <-c
      }
}

Tested on: The Go Playground

References:

[1][Golang] Use Defer to Wait For Goroutines to Finish
[2][Golang] Wait For Goroutine to Finish
[3]Behavior of defer function in named return function : golang
[4]Higher order functions. Why not? : golang