Closure

Si può definire una variabile che ha per valore una funzione, come nel segmento di codice:

func main() {
  add := func(x, y int) int {
    return x + y
  }
  fmt.Println(add(1,1))
}

Questo è un esempio di closure, ed implica che le funzioni sono oggetti primari alla stregua di variabili.

Un altro esempio di segmento di codice può essere:

func main() {
  x := 0
  increment := func() int {
    x++
    return x
  }
  fmt.Println(increment())
  fmt.Println(increment())
}

Un'altra versione di closure è una funzione che ritorna un'altra funzione, come nel programma seguente.

(150closures.go):

package main

import "fmt"

// Una funzione può ritornare un'altra funzione
// inteSeq ritorna una funzione func che ritorna un int
// Questa è una funzione anonima
func intSeq() func() int {
	i := 0
	return func() int {
		i += 1
		return i
	}
}

func main() {

	// Qui nextInt è una funzione
	nextInt := intSeq()
	// i viene inizializzato a zero

	// Esempi di invocazione
	// La funzione anonima mantiene il suo stato statico
	// la variabile i non viene risettata
	fmt.Println(nextInt())
	fmt.Println(nextInt())
	fmt.Println(nextInt())

	// Un'invocazione di intSeq con altra assegnazione
	// crea un'altra funzione anonima diversa, col suo stato
	newInts := intSeq()
	fmt.Println(newInts())
}
// E' un modo per simulare l'indicazione 'static'
// di C++ e Java