Functions in Depth

Overview

Functions are fundamental building blocks in Go. They support multiple return values, named returns, variadic parameters, and closures.

Function Declaration

func name(params) returnType {
    // body
}

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

func greet(name string) {
    fmt.Println("Hello,", name)
}

Multiple Return Values

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

result, err := divide(10, 2)

Named Return Values

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

Variadic Functions

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

sum(1, 2, 3)           // 6
sum([]int{1, 2, 3}...) // Spread slice

Closures

Functions can capture variables from their enclosing scope:

func counter() func() int {
    count := 0
    return func() int {
        count++
        return count
    }
}

c := counter()
c()  // 1
c()  // 2
c()  // 3

Defer

Defer postpones execution until the surrounding function returns:

func readFile(name string) error {
    f, err := os.Open(name)
    if err != nil {
        return err
    }
    defer f.Close()  // Executes when function returns

    // Use file...
    return nil
}

Defer Order (LIFO)

defer fmt.Println("1")
defer fmt.Println("2")
defer fmt.Println("3")
// Output: 3, 2, 1

Function Signatures

// Function type
type Operation func(int, int) int

func apply(op Operation, a, b int) int {
    return op(a, b)
}

add := func(a, b int) int { return a + b }
result := apply(add, 2, 3)  // 5

Summary

Feature Syntax
Multiple returns func f() (T1, T2)
Named returns func f() (x T1, y T2)
Variadic func f(args ...T)
Closure func() { /* capture vars */ }
Defer defer cleanup()