Functions
Functions are the primary unit of code reuse in Go. Go functions are first-class values — they can be assigned to variables, passed as arguments, and returned from other functions.
Declaring a Function
The basic syntax is func name(params) returnType { body }:
package main
import "fmt"
func add(a int, b int) int {
return a + b
}
func main() {
result := add(3, 4)
fmt.Println(result) // 7
}When consecutive parameters share a type, you can group them:
package main
import "fmt"
func multiply(a, b int) int {
return a * b
}
func main() {
fmt.Println(multiply(6, 7)) // 42
}Multiple Return Values
Go functions can return more than one value. The idiomatic pattern returns a result alongside an error:
package main
import (
"errors"
"fmt"
)
func divide(a, b float64) (float64, error) {
if b == 0 {
return 0, errors.New("division by zero")
}
return a / b, nil
}
func main() {
result, err := divide(10, 3)
if err != nil {
fmt.Println("error:", err)
return
}
fmt.Printf("%.4f\n", result) // 3.3333
}Idiomatic Go: Always check errors. The convention
result, err := f()followed byif err != nilappears throughout the standard library and idiomatic Go code.
Named Return Values
You can name the return values in the function signature. Named returns act like local variables and can be returned with a bare return:
package main
import "fmt"
func minMax(nums []int) (min, max int) {
min, max = nums[0], nums[0]
for _, n := range nums[1:] {
if n < min {
min = n
}
if n > max {
max = n
}
}
return // naked return
}
func main() {
lo, hi := minMax([]int{3, 1, 4, 1, 5, 9, 2, 6})
fmt.Println(lo, hi) // 1 9
}Use named returns sparingly — they are most useful when the function body is short and the names add clarity to the signature.
Variadic Functions
A variadic function accepts a variable number of arguments. The final parameter uses the ... prefix:
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
fmt.Println(sum(10, 20, 30, 40)) // 100
nums := []int{5, 6, 7}
fmt.Println(sum(nums...)) // 18 — spread a slice with ...
}Functions as Values
Functions are first-class citizens in Go:
package main
import "fmt"
func apply(nums []int, fn func(int) int) []int {
result := make([]int, len(nums))
for i, n := range nums {
result[i] = fn(n)
}
return result
}
func main() {
double := func(n int) int { return n * 2 }
fmt.Println(apply([]int{1, 2, 3, 4}, double)) // [2 4 6 8]
}Key Takeaways
- Functions are declared with
func name(params) returnType. - Go supports multiple return values; the
(result, error)pair is idiomatic for fallible operations. - Named return values can simplify code but should be used with care.
- Variadic functions accept a variable-length argument list; spread a slice with
.... - Functions are values — assign them to variables and pass them around freely.