>_ Golang Step By Step
Intern

Functions

Define, call, and return values from functions

# Declaring Functions

Functions are declared with func. Parameters have their type after the name, and the return type comes after the parameter list.

package main

import "fmt"

func greet(name string) string {
    return "Hello, " + name + "!"
}

func main() {
    msg := greet("Gopher")
    fmt.Println(msg)
}

# Multiple Return Values

Go functions can return multiple values. The most common pattern is returning a result and an error:

func divide(a, b float64) (float64, error) {
    if b == 0 {
        return 0, fmt.Errorf("cannot divide by zero")
    }
    return a / b, nil
}

func main() {
    result, err := divide(10, 3)
    if err != nil {
        fmt.Println("Error:", err)
        return
    }
    fmt.Printf("Result: %.2f\n", result)
}

# Variadic Functions

Use ...Type to accept a variable number of arguments. Inside the function, it becomes a slice:

func sum(nums ...int) int {
    total := 0
    for _, n := range nums {
        total += n
    }
    return total
}

fmt.Println(sum(1, 2, 3))       // 6
fmt.Println(sum(10, 20))         // 30

nums := []int{4, 5, 6}
fmt.Println(sum(nums...))      // spread a slice

# Anonymous Functions & Closures

Functions are first-class values in Go. You can assign them to variables, pass them as arguments, and return them:

func makeCounter() func() int {
    count := 0
    return func() int {
        count++
        return count
    }
}

func main() {
    counter := makeCounter()
    fmt.Println(counter()) // 1
    fmt.Println(counter()) // 2
    fmt.Println(counter()) // 3
}

# defer — Cleanup on Exit

defer schedules a function to run when the enclosing function returns. Deferred calls execute in LIFO (stack) order:

func readFile(path string) error {
    f, err := os.Open(path)
    if err != nil {
        return err
    }
    defer f.Close() // always runs on return

    // ... work with file ...
    return nil
}

⚡ Key Takeaways

  • Functions return multiple values — the (result, error) pattern is idiomatic
  • Functions are first-class values — assign, pass, return them freely
  • Closures capture variables by reference, not by value
  • defer runs on function exit, in LIFO order — great for cleanup
  • Use ...Type for variadic parameters (becomes a slice inside)
practice & review