Functions are fundamental building blocks in Go. Understanding function declaration, parameters, and return values is essential. For more context, see Go Installation Guide, Go Ecosystem Overview, Go Best Practices.
Function Declaration
Basic Function
package main
import "fmt"
func greet(name string) {
fmt.Printf("Hello, %s!\n", name)
}
func main() {
greet("Alice")
}
Function with Return Value
package main
import "fmt"
func add(a int, b int) int {
return a + b
}
func main() {
result := add(5, 3)
fmt.Println(result) // 8
}
Function with Multiple Parameters
package main
import "fmt"
func calculate(a int, b int, operation string) int {
switch operation {
case "add":
return a + b
case "subtract":
return a - b
case "multiply":
return a * b
default:
return 0
}
}
func main() {
fmt.Println(calculate(10, 5, "add")) // 15
fmt.Println(calculate(10, 5, "subtract")) // 5
}
Simplified Parameter Types
package main
import "fmt"
// When consecutive parameters have same type, can omit type
func add(a, b, c int) int {
return a + b + c
}
func main() {
fmt.Println(add(1, 2, 3)) // 6
}
Multiple Return Values
Multiple Returns
package main
import "fmt"
func divide(a, b float64) (float64, error) {
if b == 0 {
return 0, fmt.Errorf("division by zero")
}
return a / b, nil
}
func main() {
result, err := divide(10, 2)
if err != nil {
fmt.Println("Error:", err)
} else {
fmt.Println("Result:", result) // 5
}
}
Named Return Values
package main
import "fmt"
func divide(a, b float64) (result float64, err error) {
if b == 0 {
err = fmt.Errorf("division by zero")
return
}
result = a / b
return
}
func main() {
result, err := divide(10, 2)
if err != nil {
fmt.Println("Error:", err)
} else {
fmt.Println("Result:", result)
}
}
Variadic Functions
Variable Number of Arguments
package main
import "fmt"
func sum(numbers ...int) int {
total := 0
for _, n := range numbers {
total += n
}
return total
}
func main() {
fmt.Println(sum(1, 2, 3)) // 6
fmt.Println(sum(1, 2, 3, 4, 5)) // 15
fmt.Println(sum()) // 0
}
Variadic with Other Parameters
package main
import "fmt"
func printWithPrefix(prefix string, items ...string) {
for _, item := range items {
fmt.Printf("%s: %s\n", prefix, item)
}
}
func main() {
printWithPrefix("Item", "apple", "banana", "cherry")
}
Unpacking Slices
package main
import "fmt"
func sum(numbers ...int) int {
total := 0
for _, n := range numbers {
total += n
}
return total
}
func main() {
numbers := []int{1, 2, 3, 4, 5}
result := sum(numbers...) // Unpack slice
fmt.Println(result) // 15
}
Function Types
Function as Type
package main
import "fmt"
type Operation func(int, int) int
func add(a, b int) int {
return a + b
}
func subtract(a, b int) int {
return a - b
}
func main() {
var op Operation
op = add
fmt.Println(op(10, 5)) // 15
op = subtract
fmt.Println(op(10, 5)) // 5
}
Function as Parameter
package main
import "fmt"
func apply(a, b int, op func(int, int) int) int {
return op(a, b)
}
func main() {
add := func(a, b int) int { return a + b }
multiply := func(a, b int) int { return a * b }
fmt.Println(apply(10, 5, add)) // 15
fmt.Println(apply(10, 5, multiply)) // 50
}
Function as Return Value
package main
import "fmt"
func makeMultiplier(factor int) func(int) int {
return func(x int) int {
return x * factor
}
}
func main() {
double := makeMultiplier(2)
triple := makeMultiplier(3)
fmt.Println(double(5)) // 10
fmt.Println(triple(5)) // 15
}
Anonymous Functions and Closures
Anonymous Functions
package main
import "fmt"
func main() {
// Anonymous function
func(name string) {
fmt.Printf("Hello, %s!\n", name)
}("Alice")
// Anonymous function assigned to variable
greet := func(name string) string {
return fmt.Sprintf("Hello, %s!", name)
}
fmt.Println(greet("Bob"))
}
Closures
package main
import "fmt"
func counter() func() int {
count := 0
return func() int {
count++
return count
}
}
func main() {
c1 := counter()
fmt.Println(c1()) // 1
fmt.Println(c1()) // 2
fmt.Println(c1()) // 3
c2 := counter()
fmt.Println(c2()) // 1 (separate closure)
}
Best Practices
✅ Good: Clear Function Names
// DO: Use descriptive function names
func calculateTotalPrice(items []Item) float64 {
// ...
}
❌ Bad: Unclear Function Names
// DON'T: Use vague names
func calc(items []Item) float64 {
// ...
}
✅ Good: Handle Errors
// DO: Return errors explicitly
func readFile(path string) ([]byte, error) {
// ...
}
✅ Good: Use Named Return Values
// DO: Use named returns for clarity
func divide(a, b float64) (result float64, err error) {
// ...
}
Summary
Go functions provide:
- Simple declaration syntax
- Multiple return values for error handling
- Variadic functions for flexible arguments
- Function types for higher-order functions
- Closures for state capture
These features enable functional programming patterns in Go.
Comments