Variadic Functions in Go
In Go, a variadic function is a function that can accept a variable number of arguments. This is extremely useful when the number of inputs is not fixed.
Go handles variadic arguments by internally converting them into a slice. Understanding this behavior is important for real-world applications.
Why Variadic Functions Are Useful
- Flexible function calls
- Cleaner APIs
- Ideal for aggregation operations
- Common in logging, math, and utilities
Basic Syntax
A variadic parameter is defined using three dots (...)
before the data type.
func functionName(param ...type) {
// param is treated as a slice
}
Simple Example: Summing Numbers
This function calculates the sum of any number of integers.
package main
import "fmt"
func sum(numbers ...int) int {
total := 0
for _, num := range numbers {
total += num
}
return total
}
func main() {
fmt.Println(sum(10, 20))
fmt.Println(sum(5, 10, 15))
fmt.Println(sum(1, 2, 3, 4, 5))
}
Each function call passes a different number of arguments, but the function logic remains the same.
How Variadic Arguments Work Internally
Inside the function, the variadic parameter behaves exactly like a slice.
func printValues(values ...int) {
fmt.Println(values)
fmt.Println(len(values))
}
This allows you to loop, index, and manipulate the values just like any other slice.
Mixing Fixed and Variadic Parameters
A function can have fixed parameters before the variadic one, but the variadic parameter must always be last.
func calculateTotal(label string, amounts ...int) {
total := 0
for _, value := range amounts {
total += value
}
fmt.Println(label, total)
}
This pattern is commonly used in billing systems, reporting tools, and analytics dashboards.
Passing a Slice to a Variadic Function
You can pass an existing slice to a variadic function
using the ... operator.
package main
import "fmt"
func average(numbers ...int) float64 {
sum := 0
for _, n := range numbers {
sum += n
}
return float64(sum) / float64(len(numbers))
}
func main() {
scores := []int{78, 85, 90, 88}
avg := average(scores...)
fmt.Println("Average:", avg)
}
This makes variadic functions very flexible when working with slices.
Real-World Example: Logging System
Variadic functions are often used in logging frameworks.
func logMessages(level string, messages ...string) {
for _, msg := range messages {
fmt.Println(level + ":", msg)
}
}
func main() {
logMessages("INFO", "Server started", "Listening on port 8080")
logMessages("ERROR", "Database connection failed")
}
This design keeps function calls clean and readable.
Common Mistakes
- Placing variadic parameter before fixed parameters
- Assuming it is not a slice internally
- Passing a slice without using
...
Best Practices
- Use variadic functions when flexibility is required
- Keep function purpose clear
- Avoid mixing too many parameters
- Prefer readability over compactness
Where Variadic Functions Are Used
- Logging systems
- Math utilities
- Formatting functions
- API wrappers
What’s Next?
In the next lesson, you will learn about Pointers in Go, which allow functions to work directly with memory addresses for performance and control.