Go keeps its language small by providing a fixed set of pre-declared built-in functions that live in no package and cannot be imported or shadowed sensibly. They handle allocation, slicing, maps, channels, and panics. This tool is a searchable reference covering each built-in’s signature, the types it accepts, and exactly when it panics.
How it works
Built-ins are part of the language spec, not the standard library, so they need
no import. Several are generic over many types (len, cap, append), while
others are restricted to specific reference types (make, close, delete).
The reference groups them by purpose:
- Allocation —
make(slices/maps/channels),new(any type, returns a pointer). - Slices —
len,cap,append,copy,clear. - Maps —
len,delete,clear. - Channels —
make,len,cap,close. - Ordered values —
min,max(Go 1.21+). - Errors/flow —
panic,recover. - Complex numbers —
complex,real,imag.
Worked example
s := make([]int, 0, 4) // len 0, cap 4
s = append(s, 1, 2, 3) // assign back: append may reallocate
n := copy(dst, s) // n = number of elements copied (min of lengths)
delete(m, "key") // no-op if key absent, never panics
close(ch) // panics if ch is nil or already closed
The key habit is reassigning the result of append, because it may return a
slice backed by a freshly allocated array.
Notes
lenandcapare the only built-ins whose results can be constant when the argument is an array or array pointer with no side effects.deleteon a missing key is a safe no-op; it never panics.panicunwinds the stack running deferred functions; arecoverinside one of those deferred functions stops the unwinding and returns the panic value.min,max, andclearrequire Go 1.21 or newer.
Common traps and edge cases
make vs new — the key distinction
new(T) allocates zeroed storage and returns *T — it works for any type. make(T) is only valid for slices, maps, and channels, and it returns the value T directly (not a pointer) because those types already carry internal pointers. Using new on a map gives you a pointer to a nil map, which will panic on the first write. Always use make for maps, slices, and channels.
The append reallocation trap
When a slice has spare capacity, append writes into the existing backing array. When capacity is full, it allocates a larger array and copies everything. If you do not capture the return value — writing append(s, x) without assigning back — you silently lose the element on the next reallocation. Always write s = append(s, x).
delete is safe, close is not
delete(m, k) on a map is a guaranteed no-op when the key is absent — it never panics, never returns an error. close(ch) on a nil channel or an already-closed channel panics immediately. Sending to a closed channel also panics. The convention is that only the sender closes a channel, and only once.
Recovering from panics
defer func() {
if r := recover(); r != nil {
log.Printf("caught panic: %v", r)
}
}()
recover only stops a panic when called directly inside a deferred function on the panicking goroutine. Called anywhere else it returns nil and has no effect.
Using min and max
smallest := min(3, 7, 1, 9) // 1
largest := max(3, 7, 1, 9) // 9
Both accept two or more arguments of any comparable ordered type: integers, floats, or strings. They require Go 1.21 — confirm with go version before using them in shared packages.