Go Functions and Errors
Functions group code into named, reusable pieces. In Go they can also return more than one value.
Creating a Function
Use func, then the name, the parameters with their types, and the return type:
Example
package main
import "fmt"
func greet(name string) {
fmt.Println("Welcome,", name)
}
func total(price int, qty int) int {
return price * qty
}
func main() {
greet("Ayesha")
fmt.Println("Bill:", total(150, 4))
}Welcome, Ayesha Bill: 600
When parameters share a type, you can write it once: func total(price, qty int) int.
Multiple Return Values
A Go function can return several values. This is used all the time in Go code.
Example
package main
import "fmt"
func divide(a, b int) (int, int) {
return a / b, a % b
}
func main() {
q, r := divide(17, 5)
fmt.Println("Quotient:", q, "Remainder:", r)
_, onlyRem := divide(20, 6)
fmt.Println(onlyRem)
}Quotient: 3 Remainder: 2 2
Use _ to ignore a value you do not need.
Handling Errors
Go has no exceptions. A function that can fail returns an error as its last value. If the error is nil, everything went well.
Example
package main
import (
"errors"
"fmt"
)
func withdraw(balance, amount int) (int, error) {
if amount > balance {
return balance, errors.New("not enough balance")
}
return balance - amount, nil
}
func main() {
balance := 5000
balance, err := withdraw(balance, 2000)
if err != nil {
fmt.Println("Error:", err)
} else {
fmt.Println("New balance:", balance)
}
balance, err = withdraw(balance, 9000)
if err != nil {
fmt.Println("Error:", err)
}
}New balance: 3000 Error: not enough balance
The pattern if err != nil { ... } is the most common line in Go programs. Always check errors right after the call, and never ignore them silently.
fmt.Errorf builds an error message with values, for example fmt.Errorf("item %s not found", name).
Variadic Functions
Put ... before a type to accept any number of arguments. Inside the function they arrive as a slice.
Example
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))
marks := []int{55, 65, 75}
fmt.Println(sum(marks...))
}6 100 195
Anonymous Functions and Closures
A function can be stored in a variable. A function that remembers variables from outside it is called a closure.
Example
package main
import "fmt"
func counter() func() int {
count := 0
return func() int {
count++
return count
}
}
func main() {
square := func(n int) int { return n * n }
fmt.Println(square(6))
next := counter()
fmt.Println(next(), next(), next())
}36 1 2 3
defer
defer delays a call until the surrounding function finishes. It is often used to close files.
Example
package main
import "fmt"
func main() {
defer fmt.Println("Goodbye")
fmt.Println("Hello")
}Hello Goodbye
| Feature | Example |
|---|---|
| Several returns | func f() (int, error) |
| Ignore a value | _, err := f() |
| Variadic | func sum(nums ...int) |
| Function value | sq := func(n int) int { return n * n } |
| Delay a call | defer file.Close() |
Exercise
Exercise
What does a Go function usually return to show that nothing went wrong?
