Skip to main content
โšก Calmops

Functions: Definition, Parameters, Return Values

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:

  1. Simple declaration syntax
  2. Multiple return values for error handling
  3. Variadic functions for flexible arguments
  4. Function types for higher-order functions
  5. Closures for state capture

These features enable functional programming patterns in Go.

Comments