V
Vel·ToolKit
Simple · Fast · Ready to use
EN
Chapter 5 of 20

Functions

Multiple returns, named returns, variadics, closures

Basic Definition

package main

import "fmt"

func add(a, b int) int {
    return a + b
}

func main() {
    fmt.Println(add(2, 3))
}

Multiple and Named Return Values

Go encourages multiple return values, idiomatically (result, error). Named return values act as pre-declared variables inside the function and pair with a bare return.

package main

import (
    "errors"
    "fmt"
)

func divide(a, b float64) (q float64, err error) {
    if b == 0 {
        err = errors.New("divide by zero")
        return
    }
    q = a / b
    return
}

func main() {
    fmt.Println(divide(10, 4))
    fmt.Println(divide(1, 0))
}

Variadic Functions

package main

import "fmt"

func sum(nums ...int) int {
    total := 0
    for _, n := range nums {
        total += n
    }
    return total
}

func main() {
    fmt.Println(sum(1, 2, 3)) // 6
    nums := []int{1, 2, 3}
    fmt.Println(sum(nums...)) // slice expansion
}

Anonymous Functions and Closures

Functions are first-class citizens: they can be assigned to variables, passed as arguments, and capture outer variables to form closures.

package main

import "fmt"

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

Functions as Parameters / Return Values

package main

import "fmt"

func apply(nums []int, f func(int) int) []int {
    out := make([]int, len(nums))
    for i, n := range nums {
        out[i] = f(n)
    }
    return out
}

func main() {
    double := apply([]int{1, 2, 3}, func(x int) int { return x * 2 })
    fmt.Println(double) // [2 4 6]
}