Functions: Definition, Parameters, Return Values
Functions are fundamental building blocks in Go. Understanding function declaration, parameters, and return values is essential.
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