Last modified: Jan 23, 2026 By Alexander Williams

Go Best Practices for Temporary Variables

Writing clean Go code is a key skill. Temporary variables are a big part of this. They are short-lived helpers in your functions.

Using them well makes your code easier to read and debug. It can also improve performance. This guide covers the best practices.

What Are Temporary Variables?

Temporary variables store intermediate results. They exist only within a limited scope. Often, they live inside a function or a loop.

Their job is to hold a value for a short time. This makes complex calculations or logic clearer. After their use, they are discarded.

Understanding Go Variable Declaration: var vs := Explained helps you choose the right way to create them.

Keep Scope as Narrow as Possible

This is the golden rule. Declare a temporary variable as close to its first use as you can. Do not declare it at the top of a function if it's only used later.

Go's block scope helps with this. Use curly braces {} to create a new block if needed. This keeps variables from leaking.


package main

import "fmt"

func processData(input []int) {
    // Good: 'sum' is declared right before the loop where it's used.
    sum := 0
    for _, value := range input {
        sum += value
    }
    fmt.Println("Sum:", sum)

    // Another temporary variable in a separate block.
    {
        // 'avg' is scoped only within these braces.
        avg := float64(sum) / float64(len(input))
        fmt.Println("Average:", avg)
    }
    // 'avg' is not accessible here, preventing accidental reuse.
}

func main() {
    data := []int{1, 2, 3, 4, 5}
    processData(data)
}
    

Sum: 15
Average: 3
    

Use Descriptive, Short Names

Name temporary variables clearly. But keep the names short. They have a small scope, so a long name is often unnecessary.

Use i, j for loop indices. Use v or val for a single value from a range. Use ok for a boolean check.

For other cases, use a meaningful abbreviation. For example, tmp for a generic temporary holder, buf for a buffer.

Follow the Go Variable Naming Rules for Beginners for consistency.


package main

import (
    "fmt"
    "strings"
)

func formatName(first, last string) string {
    // 'sb' is a clear, short name for a strings.Builder.
    var sb strings.Builder
    sb.WriteString(strings.ToUpper(first))
    sb.WriteString(" ")
    sb.WriteString(strings.ToUpper(last))
    return sb.String()
}

func findMax(nums []int) int {
    // 'max' is perfectly descriptive for this scope.
    max := nums[0]
    for _, v := range nums[1:] {
        if v > max {
            max = v
        }
    }
    return max
}

func main() {
    name := formatName("john", "doe")
    fmt.Println(name)

    numbers := []int{5, 2, 8, 1, 9}
    fmt.Println("Max is:", findMax(numbers))
}
    

JOHN DOE
Max is: 9
    

Leverage Multiple Assignment and Declaration

Go allows declaring multiple variables in one line. This is very useful for temporary variables. It keeps related declarations together.

Use it when swapping values or when functions return multiple results. It makes the intent clear and the code compact.

Learn more about Declare Multiple Variables in One Line Go for advanced patterns.


package main

import "fmt"

func main() {
    // Swapping values using multiple assignment.
    a, b := 10, 20
    fmt.Println("Before swap:", a, b)
    a, b = b, a // Temporary swap happens here.
    fmt.Println("After swap:", a, b)

    // Using multiple return values with temporary variables.
    quotient, remainder := divide(17, 5)
    fmt.Printf("17 / 5 = %d, remainder %d\n", quotient, remainder)

    // Declare multiple related temps at once.
    var x, y, z int // All default to 0.
    x = 1
    y = 2
    z = x + y
    fmt.Println("Z:", z)
}

func divide(dividend, divisor int) (int, int) {
    q := dividend / divisor
    r := dividend % divisor
    return q, r
}
    

Before swap: 10 20
After swap: 20 10
17 / 5 = 3, remainder 2
Z: 3
    

Be Mindful of Performance with Defer

The defer statement is great for cleanup. But it can affect temporary variables. A deferred function's arguments are evaluated immediately.

If you use a loop variable in a deferred function, it might not hold the value you expect. Create a new temporary variable inside the loop to fix this.


package main

import "fmt"

func main() {
    fmt.Println("Problematic defer:")
    for i := 0; i < 3; i++ {
        defer fmt.Println("Deferred i:", i) // Captures the *variable* i.
    }
    fmt.Println("Loop done.")

    fmt.Println("\nFixed with a temporary variable:")
    for i := 0; i < 3; i++ {
        temp := i // Create a new temp var scoped to this iteration.
        defer fmt.Println("Deferred temp:", temp) // Captures the value of 'temp'.
    }
    fmt.Println("Loop done.")
}
    

Problematic defer:
Loop done.
Deferred i: 2
Deferred i: 2
Deferred i: 2

Fixed with a temporary variable:
Loop done.
Deferred temp: 2
Deferred temp: 1
Deferred temp: 0
    

The deferred calls run after the loop finishes. At that point, i has the value 3. Each deferred call uses the final value of i. The fix uses a new temp variable in each iteration.

Know When to Avoid Them Entirely

Sometimes, the best temporary variable is no variable at all. Go encourages writing direct, simple code.

If a value is only used once in the next line, consider inlining the expression. This reduces clutter. But do not sacrifice readability.


package main

import (
    "fmt"
    "strconv"
)

func calculateTotal(price string, quantity int) (float64, error) {
    // Unnecessary temporary variable.
    // p, err := strconv.ParseFloat(price, 64)
    // if err != nil {
    //     return 0, err
    // }
    // total := p * float64(quantity)
    // return total, nil

    // Better: Inline the conversion.
    // The result of ParseFloat is used directly.
    // This avoids creating a short-lived 'p' variable.
    total, err := strconv.ParseFloat(price, 64)
    if err != nil {
        return 0, err
    }
    return total * float64(quantity), nil
}

func main() {
    total, err := calculateTotal("12.99", 3)
    if err != nil {
        fmt.Println("Error:", err)
        return
    }
    fmt.Printf("Total: $%.2f\n", total)
}
    

Total: $38.97
    

Conclusion

Managing temporary variables well is a sign of clean Go code. Keep their scope tight. Use short, clear names. Use Go's features like multiple assignment.

Watch out for pitfalls with defer and closures. And know when to skip the variable altogether. These practices lead to code that is easier to read, maintain, and debug.

For related topics, explore how to Check Variable Type at Runtime in Go or learn about Go Default Values for Uninitialized Variables.