HowtoGo
Home / Basics / Built-in Functions
Basics

Built-in Functions

Go has a small set of built-in functions that are always available. They work on slices, maps, channels, and other types, and they don't need to be imported.

Some built-ins like append and copy are used for slices. Others like delete and clear work with maps. Channels have close, and complex numbers have complex, real, and imag.

new and make allocate memory for different types. len and cap report the size of slices, arrays, maps, and channels. And panic/recover handle errors in goroutines.

Examples

append grows a slice, reallocating once it outruns capacity. copy moves elements between two existing slices and never grows either one.

nums := make([]int, 3, 5)
nums[0], nums[1], nums[2] = 1, 2, 3
fmt.Println(nums, len(nums), cap(nums))

nums = append(nums, 4, 5, 6)
fmt.Println(nums, len(nums), cap(nums))

dst := make([]int, 3)
n := copy(dst, nums)
fmt.Println(dst, n)
Output
[1 2 3] 3 5
[1 2 3 4 5 6] 6 10
[1 2 3] 3
FunctionDescription
append(slice []T, elems ...T) []T
append([]int{1, 2}, 3)
Appends elements to a slice, growing and reallocating the backing array when capacity runs out.
cap(v Type) int
cap(make([]int, 2, 5)) // 5
Returns the capacity of a slice, array, pointer to array, or channel.
clear(m Type)
clear(m)
Deletes every entry from a map, or zeroes every element of a slice, in place.
close(c chan<- Type)
close(jobs)
Closes a channel so no more values can be sent; a closed channel can still be drained.
complex(r, i FloatType) ComplexType
complex(3, 4) // (3+4i)
Builds a complex number from a real and an imaginary float component.
copy(dst, src []T) int
copy(dst, src)
Copies elements from src into dst up to the shorter length, returning the count copied.
delete(m map[K]V, key K)
delete(m, "cocoa")
Removes the entry for key from m. A no-op if the key isn't present.
imag(c ComplexType) FloatType
imag(3 + 4i) // 4
Returns the imaginary part of a complex number.
len(v Type) int
len("héllo") // 6
Returns the length of a string, array, slice, map, or channel.
make(T, args...) T
make([]int, 0, 10)
Allocates and initializes a slice, map, or channel, the only builtin that returns a ready-to-use T instead of *T.
max(x T, ys ...T) T
max(4, 9, 2) // 9
Returns the largest of one or more ordered values. Added in Go 1.21.
min(x T, ys ...T) T
min(4, 9, 2) // 2
Returns the smallest of one or more ordered values. Added in Go 1.21.
new(T) *T
new(int) // *int, points to 0
Allocates a zeroed value of type T and returns a pointer to it.
panic(v any)
panic("unreachable")
Stops normal execution of the current goroutine and begins unwinding its stack, running deferred calls as it goes.
print(args ...Type)
print("debug:", 42)
Writes its arguments to standard error with no formatting. Implementation-specific and meant for compiler debugging, not application output.
println(args ...Type)
println("debug:", 42)
Like print, but space-separates its arguments and appends a trailing newline.
real(c ComplexType) FloatType
real(3 + 4i) // 3
Returns the real part of a complex number.
recover() any
if r := recover(); r != nil { ... }
Regains control of a panicking goroutine. Only has an effect when called directly inside a deferred function; returns nil otherwise.

In practice

A named return lets recover attach an error to a function that panicked partway through. levels keeps whatever it held at the moment of the panic, since it was assigned before nuts hit its zero-stock check.

func loadInventory() (levels map[string]int, err error) {
    defer func() {
        if r := recover(); r != nil {
            err = fmt.Errorf("load failed: %v", r)
        }
    }()

    levels = make(map[string]int, 4)
    items := []string{"bolts", "washers", "nuts"}
    counts := []int{120, 300, 0}

    for i, item := range items {
        if counts[i] == 0 {
            panic(fmt.Sprintf("zero stock for %q", item))
        }
        levels[item] = counts[i]
    }
    return
}

The failed load still leaves levels with the entries written before the panic. append, max, delete, and clear all work the same on this data whether or not the load succeeded.

levels, err := loadInventory()
fmt.Println(levels, err)

restock := []int{10, 20, 30}
restock = append(restock, 40)
total := restock[0]
for _, n := range restock[1:] {
    total = max(total, n)
}
fmt.Println(restock, len(restock), cap(restock), total)

delete(levels, "bolts")
clear(restock)
fmt.Println(levels, restock)
Terminal
$ go run main.go
map[bolts:120 washers:300] load failed: zero stock for "nuts"
[10 20 30 40] 4 6 40
map[washers:300] [0 0 0 0]