Skip to content

Beginner · Control flow and functions · topic 8 of 46 · 35 min

Functions and multiple return values

Explanation

A function is a named block of code that takes inputs (parameters) and gives back results. Go functions can return several values, which is how they report errors: a result plus an error. Arguments are copied into the function, Go has no default parameter values, and named results can document what is returned.

Why functions?

A function lets you write a job once and use it many times by name. It also gives the job a clear name, so main reads like a list of steps: readOrder, calculateTotal, sendReceipt.

Writing a function

go
func withGST(price int) int {
	return price + price*18/100
}

func main() {
	fmt.Println(withGST(200)) // 236
}
func, the name, parameters with their types, the result type, then the body. return hands back the result.
  • The type comes after the name: price int, not int price.
  • Consecutive parameters of the same type can share it: func add(a, b int) int.
  • A function with no result simply has no type after the brackets: func greet(name string).
  • Go has no default values for parameters and no overloading (two functions with the same name). Give functions different names instead.

Multiple return values

A Go function can return more than one value. The most common pattern is a result and an error. The caller checks the error first. This replaces exceptions, which Go does not have.

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

func main() {
	q, err := divide(10, 2)
	if err != nil {
		fmt.Println("error:", err)
		return
	}
	fmt.Println(q) // 5
}
nil means "no error". The caller must handle both values or ignore one with _.
go
q, _ := divide(9, 3)        // ignore the error (only when you are sure)
lo, hi := minMax([]int{4, 9, 1})
You must receive all results; use _ for ones you do not need.

Named result values

go
func split(total int) (half, rest int) {
	half = total / 2
	rest = total - half
	return // a "naked" return sends back half and rest
}

func main() {
	fmt.Println(split(15)) // 7 8
}
Named results start at their zero values. A naked return returns them as they are.
Tip: Named results are useful as documentation (func Coordinates() (lat, long float64)) and with defer (next topics). Avoid naked returns in long functions: the reader cannot see what is being returned.

Arguments are copied

Go passes arguments by value: the function gets its own copy. Changing a parameter inside does not change the caller's variable. To let a function change the caller's value, pass a pointer (module 4). Slices and maps behave differently because the copy still points to the same underlying data; you will see why in module 3.

go
func addBonus(marks int) {
	marks += 5
}

func main() {
	m := 80
	addBonus(m)
	fmt.Println(m) // still 80
}
The function changed its own copy. Return the new value instead: m = addBonus(m).

Exported or not: the first letter

A function whose name starts with a capital letter (CalculateTotal) can be used from other packages. A lowercase name (calculateTotal) is private to its package. That is the whole visibility system in Go; there are no public/private keywords.

Careful: Common mistake: forgetting that a function with results must return on every path. func sign(n int) string { if n > 0 { return "+" } } fails with "missing return". Add a final return.
Careful: Do not ignore errors with _ just to make code compile. A silently ignored error is how bugs hide in production. Handle it, return it, or at least log it.

Need help?

Stuck on a word or an idea? Search this course, or every course, and jump straight to the explanation or a worked question.

Try:

Watch the lesson

Functions and multiple return values · 1/7

Functions

Functions let you name a job and reuse it. Go functions can also return several values.

Prefer a video by a teacher? Find free videos on “golang functions multiple return values named results tutorial” on YouTube ↗

In real life: Splitting a restaurant bill

Friends at a restaurant split a bill. The function returns the share per person and the rupees left over, and an error if the number of people is zero. The caller decides what to do with the leftover, for example adding it to the tip.

go
package main

import (
	"errors"
	"fmt"
)

func splitBill(total, people int) (share, leftover int, err error) {
	if people <= 0 {
		return 0, 0, errors.New("need at least one person")
	}
	return total / people, total % people, nil
}

func main() {
	share, left, err := splitBill(1850, 4)
	if err != nil {
		fmt.Println("error:", err)
		return
	}
	fmt.Println("Each pays", share, "and", left, "goes to tip")
}
Prints Each pays 462 and 2 goes to tip.

Practice (0/4 done)

Task 1 · Question

What does this print? func pair() (int, string) { return 7, "seven" } ... n, s := pair() fmt.Println(s, n)

Task 2 · Question

What does this print? func double(x int) { x = x * 2 } ... v := 21 double(v) fmt.Println(v)

Task 3 · Question

Which line is the bug? 1: func grade(m int) string { 2: if m >= 40 { 3: return "Pass" 4: } 5: }

Task 4 · Practice

Write func minMax(nums []int) (lo, hi int, err error) that returns the smallest and largest number, and an error if the slice is empty. Call it from main and handle the error.

Quick quiz

Question 1

1.How does a Go function usually report failure?

Question 2

2.Does Go support default parameter values?

Question 3

3.Which function can be used from another package?

Question 4

4.What is a naked return?

Read more (free)

Open a question to see the answer and why. The first ones are this topic's own quiz, so try the quiz above before you peek.

How does a Go function usually report failure?

Answer: By returning an error value as the last result

Go functions return an error as the last result; nil means success.

Does Go support default parameter values?

Answer: No

Go has no default values or overloading; use different function names or an options struct.

Which function can be used from another package?

Answer: CalculateTax

Names starting with a capital letter are exported.

What is a naked return?

Answer: A return with no values in a function with named results

With named results, return alone sends back their current values.

What does a function return if it has no return statement?Related

Answer: undefined

Without return, a function gives back undefined.

From Functions

A non-void function ends without return on one branch, and the caller uses the result. This is…Related

Answer: Undefined behaviour

gcc -Wall warns about it.

From Functions

Which keyword means "the method must assign this before returning, and the caller need not set it"?Related

Answer: out

out parameters are for results flowing out of the method.

From Parameters in depth: optional, named, ref, out, params, overloading

Is Java pass-by-value or pass-by-reference?Related

Answer: Always pass-by-value (references are copied for objects)

Java copies every argument; for objects, the copy is the reference.

From Methods: parameters, return values and overloading

Pass the quiz (60% or more) or mark this topic as done when you are ready.

Your progress is saved on this device only.

Next steps

  1. 2 more topics in “Control flow and functions” before its exam: Variadic functions, function values and closures, defer: clean up at the end.
  2. Module 2 exam: Control flow and functions · 13 questions · 20 min, without help. 5 topics of this module still to finish first.
  3. Then the next module, Collections and structs. 46 topics left in the course before the final exam.

← Previous: Loops: for is the only loop