Functions are the building blocks of Go programming, providing a powerful way to organize, reuse, and modularise code. In this deep dive, we'll explore everything you need to know about functions in Go, from basic syntax to advanced techniques.
Basic Function Syntax
Let's start with the fundamental function declaration in Go:
func functionName(parameters) returnType {
// Function body
return value
}
Here's a simple example:
func add(a int, b int) int {
return a + b
}
Function Parameters and Return Values
Multiple Parameters
Go allows multiple parameters of the same type to be declared concisely:
func add(a, b int) int {
return a + b
}
Multiple Return Values
One of Go's unique features is the ability to return multiple values:
func divideNumbers(a, b float64) (float64, error) {
if b == 0 {
return 0, errors.New("division by zero")
}
return a / b, nil
}
// Usage
result, err := divideNumbers(10, 2)
if err != nil {
// Handle error
}
Named Return Values
Go supports named return values, which can make code more readable:
func calculateStats(numbers []int) (count int, sum int, average float64) {
count = len(numbers)
for _, num := range numbers {
sum += num
}
average = float64(sum) / float64(count)
return // Naked return uses named return values
}
Variadic Functions
Functions can accept a variable number of arguments:
func sum(numbers ...int) int {
total := 0
for _, num := range numbers {
total += num
}
return total
}
// Usage
result := sum(1, 2, 3, 4, 5)
Function as First-Class Citizens
In Go, functions are first-class citizens. You can assign them to variables, pass them as arguments, and return them from other functions:
// Function type declaration
type MathFunc func(int, int) int
// Higher-order function
func operate(fn MathFunc, a, b int) int {
return fn(a, b)
}
// Usage
add := func(a, b int) int { return a + b }
result := operate(add, 5, 3)
Error Handling
Proper error handling is crucial in Go:
func processData(data string) error {
if data == "" {
return fmt.Errorf("invalid input: data cannot be empty")
}
// Process data
return nil
}
// Usage
if err := processData(""); err != nil {
log.Fatal(err)
}