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() {
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.