Skip to content

Functions

Functions are declared with the func keyword. They can have zero or more arguments, and the types of the arguments come after the names with a space. Functions can also return multiple values, and this is how error checking is done in Go. You can even instantiate the return values of the function in the function definition (only use in short functions).

By default, arguments are passed by value. To pass by reference, you need to take a pointer as the argument to modify the reference.

go
package main

import "fmt"

func add(x int, y int) int {
	return x + y
}

func swap(x, y string) (string, string) {
    return y, x
}

func split(sum int) (x, y int) {
	x = sum * 4 / 9
	y = sum - x
	return
}

func main() {
	fmt.Println(add(42, 13))
    fmt.Println(swap("foo", "bar"))
    fmt.Println(split(17))
}

Functions can also be saved as variables and passed to other functions.

go
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))
}

Closures

Closures are functions that reference variables outside of the function body. In the below example, the inner function of adder has access to its own sum.

go
package main

import "fmt"

func adder() func(int) int {
	sum := 0
	return func(x int) int {
		sum += x
		return sum
	}
}

func main() {
	pos, neg := adder(), adder()
	for i := 0; i < 10; i++ {
		fmt.Println(
			pos(i),
			neg(-2*i),
		)
	}
}

// 0 0
// 1 -2
// 3 -6
// 6 -12
// 10 -20
// 15 -30
// 21 -42
// 28 -56
// 36 -72
// 45 -90

Generics

Functions can also take generic types with the below syntax. In the below example the generic type must implement the comparable constraint, meaning it has the == and != operators.

go
func Index[T comparable](s []T, x T) int {
	for i, v := range s {
		// v and x are type T, which has the comparable
		// constraint, so we can use == here.
		if v == x {
			return i
		}
	}
	return -1
}