Functions

Go functions look familiar at first glance, but one feature sets them apart from most other languages here: a Go function can return more than one value, and that single feature shapes how error handling looks throughout the entire language.

Declaring and calling a function

Go main.go
package main

import "fmt"

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

func main() {
	sum := add(3, 4)
	fmt.Println("Sum:", sum)
}
Output
Sum: 7

func add(a int, b int) int reads as: a function named add, taking two int parameters, returning an int. When two consecutive parameters share a type, Go lets you write it once: func add(a, b int) int means the same thing.

Multiple return values

Any Go function can return more than one value, separated by commas — most commonly used to return a result alongside an error:

Go main.go
package main

import (
	"errors"
	"fmt"
)

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

func main() {
	result, err := divide(10, 2)
	if err != nil {
		fmt.Println("Error:", err)
	} else {
		fmt.Println("Result:", result)
	}

	_, err = divide(10, 0)
	if err != nil {
		fmt.Println("Error:", err)
	}
}
Output
Result: 5
Error: cannot divide by zero
Note: the pattern result, err := someCall() followed immediately by if err != nil is the single most common idiom in real Go code — there are no exceptions to throw or catch here. Every call that can fail is expected to return an error as its last value, and callers are expected to check it every time, right after the call. The underscore _ in _, err = divide(10, 0) explicitly discards a return value Go requires you to acknowledge but that you don't need.

Variadic functions

A parameter type prefixed with ... accepts any number of arguments, collected into a slice inside the function:

Go main.go
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))
	fmt.Println(sum(10, 20, 30, 40))
}
Output
6
100

fmt.Println itself is a variadic function, which is how it accepts anywhere from zero to dozens of arguments in the examples throughout this course.