Defining Simple Variables

If you’re familiar with C-style variable declarations, Go’s declaration syntax may seem backwards amd so takes a little getting used to. But it is quite straightforward and readable once you get the hang of it.

Basic Declarations Using var

One way to declare variables in Go is to use var. For example:

var n int     // n is an int initialized to 0
var s string  // s is a string initialized to ""
var a, b int  // declare a and b to be ints with initial value 0

Since we haven’t given an initial value to either variable, Go automatically assigns them the zero-value associated with that type.

You can also provide your own initial value like this:

var n int = 5          // declare n to be an int with initial value 5
var s string = "apple" // declare s to be a string with initial value "apple"

var a, b int = 2, 3    // declare a to be an int with initial value 2
                       // declare b to be an int with initial value 3

Multiple variable declarations can be grouped together like this:

var (
    n int
    s string = "apple"
    a, b int = 2, 3
)

Declarations Using var Without a Type

Go also lets you declare variables without explicitly declaring a type. For example:

var n = 3  // 3 is an int, so n is inferred to be of type int

var m = n  // m is inferred to be of type int because n is an int

Go infers the type of the variable being declared. For example, in the first declaration Go knows n is an int because the literal 3 is an int.

An even shorter form uses the := operator, e.g.:

n := 3        // declare n and initialize it to 3

s := "apple"  // declare s and initialize it to "apple"

:= is used quite often in practice since it is quick to type and easy to read.

A restriction on variable declarations using := is that they may only occur inside a function. For example, this is not allowed:

package main

import "fmt"

m := 4  // compiler error: can't use := outside functions

func main() {
    fmt.Println(m)
}

Replacing m := 4 in this example with either var m = 4 or var m int = 4 fixes the problem.

Declaring and Assigning Multiple Variables

Go lets you declare multiple variables with a single :=. For example:

name, age := "Jane", 22

You can also assign multiple variables using =. For instance, here is a convenient way to swap the values of two variables:

x, y := 1, 3

x, y = y, x    // swap x and y

// now x == 3 and y == 1

The Redeclaration Rule

One other difference between variables declared with := and those with var is that, in some cases, :=-style variables can be redeclared. For example, most programmers would not be surprised that this code doesn’t compile:

var z int
fmt.Println(z)

var z int       // compiler error: z is re-declared
fmt.Println(z)

Or that this code also fails to compile:

z := 1
fmt.Println(z)
z := 2          // compiler error: no new variables on left side of :=
fmt.Println(z)

While the error here is expected, the reason for the error is not the same as in the previous example. Here, the error message implies that it might work if you put a new variable on the left side of :=. So lets try that:

z := 1
fmt.Println(z)  // prints 1

r, z := 0, 2    // okay: this compiles!
fmt.Println(r)
fmt.Println(z)  // prints 2

The variable z has been re-declared. Allowing a variable to be re-declared seems rather odd, but the reason is to allow for things like error values. For example, many Go functions return two values, the main value of the function and an error flag. For example:

f1, err := os.Open("story1.txt")

f2, err := os.Open("story2.txt")

Without Go’s redeclaration rule, we’d have to write err1 and err2 instead of just err.

Unused Variables

Go considers unused variables errors. For example, this code won’t compile:

a := 3      // compiler error: a declared but not used
b := 4
c := 2 * b

fmt.Println(c)

Unused variables are often a sign of an error. However, it can sometimes be a nuisance in smaller programs, especially ones you might write to help understand details of the language.

The Blank Identifier

Another variable you will often see in Go is _, which is known as the blank identifier. It’s normally used when you need a variable you don’t care about. For example:

f, _ := os.Open("story.txt")

The _ indicates we don’t care about the second value (which happens to be an error flag) that os.Open returns.

Questions

  1. Show three different ways to declare a variable of type string whose initial value is "" (the empty string).

  2. Is the following statement legal in Go?

    var x
    

    Why, or why not?

  3. Is the following statement legal in Go?

    var x := 3
    

    Why, or why not?

  4. Explain in brief, clear English, when you are allowed to redeclare a variable in a block of code.

  5. What is the blank identifier? Give an example of how it can be used in Go.