Declaration

The zero value declaration for a variable is done using the var keyword and by specifying the name and type; for example, var a int. This could be counter-intuitive for a person that comes from another language, like Java, where type and name order is inverted, but it's actually more human readable.

The var a int example describes a variable (var) with a name, a, that is an integer (int). This kind of expression creates a new variable with a zero-value for the selected type:

 

The other way of initiating a variable is by assignment, which can have an inferred or specific type. An inferred type is achieved with the following:

  • The variable name, followed by the := operator and the value (for example, a := 1), also called short declaration.
  • The var keyword, followed by the name, the = operator, and a value (for example, var a = 1).

Note that these two methods are almost equivalent, and redundant, but the Go team decided to keep them both for the sake of the compatibility promise of Go 1. The main difference in terms of the short declaration is that the type cannot be specified and it's inferred by the value.

An assignment with a specific type is made with a declaration, followed by an equals sign and the value. This is very useful if the declared type is an interface, or if the type that's inferred is incorrect. Here are some examples:

var a = 1             // this will be an int
b := 1 // this is equivalent
var c int64 = 1 // this will be an int64

var d interface{} = 1 // this is declared as an interface{}

Some types need to use built-in functions so that they can be initialized correctly:

  • new makes it possible to create a pointer of a certain type while already allocating some space for the underlying variable.
  • make initializes slices, maps, and channels:
  • Slices need an extra argument for the size, and an optional one for the capacity of the underlying array.
  • Maps can have one argument for their initial capacity.
  • Channels can also have one argument for its capacity. They are unlike maps, which cannot change.

The initialization of a type using a built-in function is as follows: 

a := new(int)                   // pointer of a new in variable
sliceEmpty := make([]int, 0) // slice of int of size 0, and a capacity of 0
sliceCap := make([]int, 0, 10) // slice of int of size 0, and a capacity of 10
map1 = make(map[string]int) // map with default capacity
map2 = make(map[string]int, 10) // map with a capacity of 10
ch1 = make(chan int) // channel with no capacity (unbuffered)
ch2 = make(chan int, 10) // channel with capacity of 10 (buffered)