go go/book/learninggo

Go Variable Declaration: := vs var and Their Scope

In Go, variables can be declared using either the short declaration operator (:=) or the var keyword. While they may seem similar, they differ in their behavior and scope.

1. := (Short Variable Declaration)

The := operator is used for short variable declarations and is limited to the block scope where it is declared. It is shorthand for declaring and initializing a variable at the same time.

Characteristics:

  • Only allowed inside functions (not at the package level).
  • Declares variables with block-local scope.
  • Automatically infers the type from the initializer.

Example:

func example() {
    x := 10 // x is declared and initialized to 10, scoped to this block.
    if x > 5 {
        y := 20 // y is scoped only to this if block.
        fmt.Println(x, y) // Outputs: 10, 20
    }
    // fmt.Println(y) // Error: y is not defined here.
}

When to Use:

  • When declaring temporary variables in a small scope (e.g., within a function or block).
  • To keep code concise and readable for local computations.

2. var (Explicit Declaration)

The var keyword is used for explicit variable declarations and can be used at both the package level and inside functions. You can declare variables without immediately initializing them.

Characteristics:

  • Can be used anywhere (package-level or block-level).
  • Allows declaration without initialization (defaults to zero value).
  • Provides more clarity in cases requiring type specification.

Example:

var x int // x is declared at package level or block level.
x = 10    // Initialization can happen later.
 
func example() {
    var y int = 20 // y is explicitly declared and initialized to 20.
    fmt.Println(x, y)
}

When to Use:

  • When defining global variables at the package level.
  • When you want to initialize a variable later.
  • For increased readability when type clarity is needed.

Key Differences Between := and var

Feature:=var
ScopeLimited to the current block.Can be global (package-level) or block-level.
InitializationRequires initialization.Optional (defaults to zero value).
Type InferenceAutomatically inferred.Can be inferred or explicitly specified.
Usage RestrictionOnly allowed inside functions.Allowed everywhere.

3. Practical Examples

Block-Scoped Variables (:=):

func main() {
    x := 5
    if x > 3 {
        y := 10 // y exists only inside the if block.
        fmt.Println(y)
    }
    // fmt.Println(y) // Error: y is undefined here.
}

Global Variables (var):

var appName = "MyApp" // Package-level variable, accessible everywhere.
 
func main() {
    fmt.Println(appName) // Outputs: MyApp
}

Mixed Usage:

var counter int // Global variable.
 
func increment() {
    counter += 1 // Accessing global variable.
    localMessage := "Incremented!" // Local variable.
    fmt.Println(localMessage, counter)
}

Summary

  • Use := for local variables within functions or small scopes.
  • Use var for global variables or when a variable needs to be initialized later.
  • Be mindful of scope to avoid unintended variable shadowing. For example:
    x := 10
    {
        x := 20 // This creates a new x, shadowing the outer one.
        fmt.Println(x) // Outputs: 20
    }
    fmt.Println(x) // Outputs: 10