Functions
A function in Go is declared with func, and at first glance there is nothing to dig into: a name, parentheses with parameters, a return type, a body. But the function is the core unit of code, and it hosts a few idioms you cannot read real Go without: a function returns several values at once, and the value, err pair is the scaffold of all error handling; the ...int ellipsis parameter takes any number of arguments; the function itself is a value you can put in a variable and pass along.
Under the simple func sits the model interviews actually probe: multiple return is not a tuple but several separate values; named results are pre-declared and zeroed; a variadic parameter is an ordinary slice inside; a first-class function passes as an argument; and recursion grows the goroutine stack because Go guarantees no tail-call optimization. This topic walks functions layer by layer — from returns to recursion.
Topic map
- Multiple & Named Returns —
func f() (int, error)returns several values; thereturn value, erridiom; named results(n int, err error)are pre-declared and zeroed, and a nakedreturnships them — but don't lean on it. - Variadic Functions —
func f(xs ...int): inside,xsis an ordinary[]int; call it with a set of arguments or "spread" an existing slice viaf(s...); the variadic parameter is always last. - Functions as Values — first-class functions: assign them to variables, pass them as arguments, return them from functions; the function type
func(int) int; anonymous functions and the immediately-invokedfunc(){…}(). - Recursion — a function calling itself; the mandatory base case; Go guarantees no tail-call optimization, so deep recursion grows the goroutine stack — for hot deep loops iteration is preferable.
Common mistakes and traps
| Mistake | Consequence |
|---|---|
| Treating multiple return as a tuple you can assign to one variable | It is N separate values: v, err := f() — each needs its own variable (or _) |
Ignoring the second return value err | The error is silently dropped — the root of most bugs in Go code |
| Thinking a named result must be initialised by hand | It is pre-declared and already zeroed (0, "", nil); a naked return ships its current value |
Overusing a naked return in a long function | It is unclear what was actually returned — reviewers treat it as an anti-pattern |
Passing a slice into a variadic function without ... | f(s) treats the slice as one argument — you need f(s...) to spread it |
| Putting the variadic parameter anywhere but last | Compile error — ...T must be the last parameter in the list |
| Forgetting the base case in recursion | Endless self-calls grow the goroutine stack to a stack overflow panic |
| Counting on tail-call optimization like in functional languages | Go does not guarantee it — deep recursion eats the stack; for hot loops use iteration |
Why it matters for interviews
Functions are a common junior block: the question is never "how do you declare a func" but whether you grasp the idioms behind it. A candidate who copied code from examples but never studied the model stumbles right here.
What interviewers usually check:
- How multiple return works and why the
value, errpair is the basis of error handling. - What named results are, why they are convenient, and why a naked
returnshould not be overused. - That a variadic parameter
...Tis a slice inside, and how to "spread" an existing slice vias.... - That functions in Go are first-class values: you can assign, pass, and return them.
- Why deep recursion in Go is dangerous (no guaranteed tail-call optimization, the stack grows) and when to use iteration instead.