Go Closures

November 15, 2020   

Notes from:

Closures in general have always confused me. I basically don’t understand what people are talking about!

First before understanding closures you need to note how an anonymous function looks in Go

Here x is assigned an anonymous function.

package main

import "fmt"

func y() {
  fmt.Println("You are anonymous!")
}


func main() {

  x := func() { fmt.Println("I am anonymous!") }
  x()
  x = y
  x()
}

Is it anonymous anymore if its called x? Notice how x can hold a y?

Ok, so what is a closure:

“A closure is a special type of anonymous function that references variables declared outside the function itself” (Jon Calhoun)

We can use variables that weren’t passed into the function as a parameter but insted were available when the function was declared. Example taken from Johns site:

package main

import "fmt"

func main() {
  n := 0
  counter := func() int {
    n += 1
    return n
  }
  fmt.Println(counter())
  fmt.Println(counter())
}

prints: 1, 2 as the “n” is like a global variable. This means this closure can have side effects to remove those we can rewrite this as:

package main

import "fmt"

func main() {
  counter := newCounter()
  fmt.Println(counter())
  fmt.Println(counter())
}

func newCounter() func() int {
  n := 0
  return func() int {
    n += 1
    return n
  }
}

This will still print 1, 2 but it keeps things in main from mutating “n” and causing the counter to be incorrect.

This allows us to persist data between function calls will also isolating the data from other code.