The var statement declares a list of variables.

var c, python, java bool

A var declaration can include initializers, one per variable. Type can be omitted as it will be inferred from the value.

var c, python, java = true, false, "no!"

Go assigns a default zero value to all declared variables with no explicit value assigned.

You can also wrap vars in a declaration list:

var (
    x    int
    y        = 20
    z    int = 30
    d, e     = 40, "hello"
    f, g string
)

Declare multiple variables on the same line only when assigning multiple values returned from a function or the comma ok idiom.

Try to declare only the immutable variables on the package level, so it’s easier to track data flow in your app.

Short var declaration

:= is a short assignment statement to replace var declaration with implicit type. These are equivalent:

var x = 1
x := 1

Type is inferred from the value.

This operator cannot be used outside of a function, because every statement must begin with a keyword (e.g. var, func etc.).

The := operator allows you to assign values to existing variables too. As long as at least one new variable is on the lefthand side of the :=, any of the other variables can already exist:

x := 10
x, y := 30, "hello"

But I find it confusing.

When to use var or :=

Inside functions the most common is :=. In some cases it’s recommended to avoid it when:

  • When initializing variable with zero value, use var x int.
  • When the default type of the literal is not the type you want for a variable, use var x byte = 20 instead of x := byte(20).
  • To avoid shadowing variables, explicitly declare variables with var at the start of the block, and use = operator to assign values.

Constants

const keyword is used to declare a constant.

const Pi = 3.14
const (
	Big = 100
	Small = 1
)

Constants cannot be declared using the := syntax.

Numeric constants are high-precision values.

Types

Literals

Pointers

Const

const keyword.

Constants in Go are a way to give names to literals. There is no way in Go to declare that a variable is immutable.

Constants in Go are very limited. They can only hold values that can be processed in the compile time:

  • Numeric literals
  • true and false
  • Strings
  • Runes
  • The values returned by the built-in functions complex, real, imag, len, and cap
  • Expressions that consist of operators and the preceding values

That means that a const value can’t be calculated in the runtime.

Constant can be typed or untyped:

const x = 10
const typedX int = 10

This constant can be assigned directly only to an int. Assigning it to any other type produces a compile-time error like this:

cannot use typedX (type int) as type float64 in assignment

Unused variables

Go throws a compile-time error when a variable is declared and not used.

The Go compiler won’t stop you from creating unread package-level variables. This is one more reason you should avoid creating package-level variables.

Perhaps surprisingly, the Go compiler allows you to create unread constants with const. This is because constants in Go are calculated at compile time and cannot have any side effects. This makes them easy to eliminate: if a constant isn’t used, it is simply not included in the compiled binary.

Ignore returned values

Scope

Imports and declarations outside of functions are in the file block. Within a function every set of braces {} is a new block. Variables are scoped to it.

Variables can be shadowed (shadowing variable).

func main() {
    x := 10
    if x > 5 {
        x, y := 5, 20
        fmt.Println(x, y) // 5 20
    }
    fmt.Println(x) // 10
}

Go has universe block - it’s a block where all built-in types (int, string), constants (true, false), functions (make, close), nil “lives”. Go doesn’t define them as keywords, but treats them as predeclared identifiers and puts them in the universe block that opens the possibility to shadow them as well.

fmt.Println(true) // true
true := 10
fmt.Println(true) // 10