Skip to main content

Functions: Definition, Parameters, Return Values

Created: December 17, 2025 4 min read

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:

  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.

Resources

Comments

Share this article

Scan to read on mobile