More Functions

Function Values

Functions are values too. They can be passed around just like other values. Function values may be used as function arguments and return values.

Example

package main

import (
	"fmt"
	"math"
)

func compute(fn func(float64, float64) float64) float64 {
	return fn(3, 4)
}

func main() {
	hypot := func(x, y float64) float64 {
		return math.Sqrt(x*x + y*y)
	}
	fmt.Println(hypot(5, 12))
	fmt.Println(compute(hypot))
	fmt.Println(compute(math.Pow))	
}
13
5
81

Function Closures

Go functions may be closures. A closure is a function value that references variables from outside its body. The function may access and assign to the referenced variables; in this sense the function is "bound" to the variables.

Example 1 (No Parameter)

package main

import "fmt"

func increment() func() int {
    var x int
    return func() int {
        x++
        return x
    }
}

func main() {
    a := increment()
    b := increment()
    
    fmt.Println("a: ", a())
    fmt.Println("a: ", a())
    fmt.Println("a: ", a())
    
    fmt.Println("b: ", b())
}
a:  1
a:  2
a:  3
b:  1

Notice here a and b have their own closure and each is bound to its own x variable

Example 2 (With Parameter)

package main

import "fmt"

func adder() func(int) int {	// two return types: a func and an int
	sum := 0
	return func(x int) int {		// return an anonymous function
		sum += x
		return sum
	}
}

func main() {
	pos, neg := adder(), adder()
	for i := 0; i < 10; i++ {
		fmt.Println(
			pos(i),
			neg(-1*i),
		)
	}
}
0 0
1 -1
3 -3
6 -6
10 -10
15 -15
21 -21
28 -28
36 -36
45 -45

The adder function returns a closure. Each closure is bound to its own sum variable.

More About Closure

Great article!

Last updated