Functions in Go
Learn how to define and use functions in Go, including multiple return values, variadic parameters, closures, recursion, and methods
Functions are the fundamental building blocks of Go programs. They package reusable logic, accept inputs through parameters, and hand results back through return values. Beyond the entry point func main() you’ve already seen, Go encourages breaking programs into small, well-named functions that each do one thing clearly.
Go’s functions have a few characteristics that set them apart from many other procedural languages. Most notably, a function can return multiple values at once — a feature Go leans on heavily for returning a result alongside an error. Functions are also first-class values: you can store them in variables, pass them as arguments, and return them from other functions, which makes closures and higher-order patterns natural to write.
In this tutorial you’ll learn how to define functions, work with parameters and multiple return values, use variadic and named returns, write recursive functions, build closures, and attach methods to your own types.
Defining Functions
A Go function is declared with the func keyword, a name, a parameter list (each with a type), and an optional return type. When consecutive parameters share a type, you can write the type just once (a, b int).
Create a file named functions.go:
| |
Here divmod returns two values that the caller receives with a single := assignment. The stats function shows named return values: sum and count are declared in the signature, used like local variables, and returned by a bare return.
Recursion and Variadic Functions
Go supports recursion just like other procedural languages — a function may call itself. Go also supports variadic functions, which accept any number of trailing arguments collected into a slice using the ... syntax.
Create a file named recursion.go:
| |
Inside sum, the parameter numbers is an []int slice. You can call it with separate arguments or expand an existing slice into the call with nums....
Closures and Higher-Order Functions
Because functions are first-class values in Go, a function can return another function or accept one as a parameter. A function that captures and remembers variables from its surrounding scope is called a closure.
Create a file named closures.go:
| |
Each call to counter() produces a fresh closure with its own private count variable. The apply function demonstrates the higher-order pattern: it accepts fn func(int) int and calls it for each element.
Methods on Types
A method is a function with a special receiver argument bound to a type. Methods are how Go associates behavior with your own types, such as structs. A value receiver operates on a copy, while a pointer receiver can modify the original.
Create a file named methods.go:
| |
Area uses a value receiver (r Rectangle) because it only reads fields. Scale uses a pointer receiver (r *Rectangle) so its changes persist on the original rect. Go automatically takes the address of rect when you call rect.Scale(2), so you don’t need to write (&rect).Scale(2).
Running with Docker
Run each example with the official Go image — no local Go installation required.
| |
Expected Output
Running functions.go:
Hello, Gopher!
3 + 4 = 7
17 / 5 = 3 remainder 2
sum=60 count=3
Running recursion.go:
5! = 120
sum(1,2,3) = 6
sum(4,5,6,7) = 22
sum(nums...) = 60
Running closures.go:
1
2
3
[2 4 6 8]
Running methods.go:
Area: 12.0
After scaling: 6.0 x 8.0
New area: 48.0
Key Concepts
- Type-after-name syntax — Parameters and return types are written as
name type, and shared types can be collapsed (a, b int). - Multiple return values — Go functions can return several values at once, the idiomatic way to return a result alongside an
error. - Named return values — Naming returns in the signature lets you use a bare
return, which can clarify intent in short functions. - Variadic parameters —
...intcollects trailing arguments into a slice; expand an existing slice into a call withslice.... - First-class functions — Functions are values you can store in variables, pass as arguments, and return from other functions.
- Closures — An inner function captures variables from its enclosing scope, giving each closure its own private state.
- Methods and receivers — Methods bind behavior to a type; use a value receiver to read and a pointer receiver to modify the original.
- Capitalization controls visibility — An exported (capitalized) name like
Areais visible outside its package; a lowercase name likegreetis package-private.
Comments
Loading comments...
Leave a Comment