Functions & Returns
Functions are reusable blocks of code that perform specific tasks. In this lesson, you'll learn how to define functions, pass parameters, return values, and use Go's unique features like multiple return values and variadic parameters.
Function Basics
A function is declared using the func keyword:
Click Run to execute your code
func functionName(param1 type1, param2 type2) returnType {
// function body
return value
}
func- keyword to declare a functionfunctionName- name of the functionparameters- input values (optional)returnType- type of value returned (optional)
Functions Without Return Values
func greet(name string) {
fmt.Printf("Hello, %s!\n", name)
}
func main() {
greet("Alice") // Hello, Alice!
}
Functions With Return Values
func add(a int, b int) int {
return a + b
}
func main() {
result := add(5, 3)
fmt.Println(result) // 8
}
func add(a, b int) int
Multiple Return Values
One of Go's most powerful features is the ability to return multiple values from a function:
Click Run to execute your code
func functionName(params) (type1, type2, type3) {
return value1, value2, value3
}
Common Pattern: Returning Error
The most common use of multiple returns is returning a value and an error:
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, 2)
if err != nil {
fmt.Println("Error:", err)
return
}
fmt.Println("Result:", result)
}
Named Return Values
You can name return values in the function signature. Named returns are automatically initialized to their zero values:
func split(sum int) (x, y int) {
x = sum * 4 / 9
y = sum - x
return // "naked" return
}
func main() {
a, b := split(17)
fmt.Println(a, b) // 7 10
}
Named Returns for Documentation
// Named returns make the function signature self-documenting
func getCoordinates() (x, y, z float64) {
x = 10.5
y = 20.3
z = 5.7
return
}
// vs unnamed returns (less clear)
func getCoordinates() (float64, float64, float64) {
return 10.5, 20.3, 5.7
}
Variadic Functions
Variadic functions accept a variable number of arguments:
Click Run to execute your code
func functionName(args ...type) {
// args is a slice of type
}
- The
...before the type makes it variadic - Inside the function, args is a slice
- Must be the last parameter
Passing a Slice to Variadic Function
func sum(numbers ...int) int {
total := 0
for _, num := range numbers {
total += num
}
return total
}
func main() {
// Pass individual values
fmt.Println(sum(1, 2, 3)) // 6
// Pass a slice using ...
nums := []int{1, 2, 3, 4, 5}
fmt.Println(sum(nums...)) // 15
}
Function Parameters
Pass by Value
Go passes arguments by value (copies the value):
func modify(x int) {
x = 100 // Only modifies the copy
}
func main() {
num := 5
modify(num)
fmt.Println(num) // Still 5
}
Pass by Reference (Using Pointers)
To modify the original value, pass a pointer:
func modify(x *int) {
*x = 100 // Modifies the original
}
func main() {
num := 5
modify(&num)
fmt.Println(num) // Now 100
}
Functions as Values
Functions are first-class citizens in Goβthey can be assigned to variables:
func main() {
// Assign function to variable
add := func(a, b int) int {
return a + b
}
result := add(5, 3)
fmt.Println(result) // 8
// Pass function as argument
operate(10, 5, add)
}
func operate(a, b int, op func(int, int) int) {
result := op(a, b)
fmt.Println("Result:", result)
}
Common Mistakes
1. Ignoring return values
// β Wrong - ignoring error
result, _ := divide(10, 0) // Don't ignore errors!
fmt.Println(result)
// β
Correct - check errors
result, err := divide(10, 0)
if err != nil {
fmt.Println("Error:", err)
return
}
fmt.Println(result)
2. Wrong number of return values
// β Wrong - function returns 2 values
func getValues() (int, int) {
return 5, 10
}
x := getValues() // Error: multiple-value in single-value context
// β
Correct - capture both values
x, y := getValues()
// Or ignore one
x, _ := getValues()
3. Modifying parameters expecting change
// β Wrong - won't modify original
func double(x int) {
x = x * 2
}
num := 5
double(num)
fmt.Println(num) // Still 5
// β
Correct - use pointer or return value
func double(x *int) {
*x = *x * 2
}
num := 5
double(&num)
fmt.Println(num) // 10
4. Variadic parameter not last
// β Wrong - variadic must be last
func process(nums ...int, name string) {
// Error!
}
// β
Correct - variadic parameter last
func process(name string, nums ...int) {
// OK
}
Exercise: Statistics Calculator
Task: Create functions to calculate statistics for a set of numbers.
Requirements:
- Create a variadic function
averagethat calculates the mean - Create a function
minMaxthat returns both minimum and maximum - Test with the numbers: 5, 2, 8, 1, 9, 3
- Print average, min, and max
Show Solution
package main
import "fmt"
// Calculate average of numbers
func average(numbers ...float64) float64 {
if len(numbers) == 0 {
return 0
}
sum := 0.0
for _, num := range numbers {
sum += num
}
return sum / float64(len(numbers))
}
// Find minimum and maximum
func minMax(numbers ...float64) (min, max float64) {
if len(numbers) == 0 {
return 0, 0
}
min = numbers[0]
max = numbers[0]
for _, num := range numbers {
if num < min {
min = num
}
if num > max {
max = num
}
}
return
}
func main() {
numbers := []float64{5, 2, 8, 1, 9, 3}
// Calculate average
avg := average(numbers...)
fmt.Printf("Average: %.2f\n", avg)
// Find min and max
min, max := minMax(numbers...)
fmt.Printf("Min: %.2f, Max: %.2f\n", min, max)
// Bonus: Calculate range
rangeValue := max - min
fmt.Printf("Range: %.2f\n", rangeValue)
}
Summary
- Functions are declared with the
funckeyword - Parameters are passed by value (copied)
- Multiple return values are a key Go feature
- Error handling uses return values, not exceptions
- Named returns can improve readability
- Variadic functions accept variable number of arguments
- Functions are values and can be assigned to variables
- Use pointers to modify original values
What's Next?
Now that you understand basic functions, you're ready to learn about Closures & Defer. In the next lesson, you'll discover anonymous functions, closures, and the defer statement for resource cleanup.
Enjoying these tutorials?