Skip to content

Variables

Variables are storage locations that hold values, allowing the stored values to change dynamically at runtime. Each variable declared allocates a piece of memory to store a value of the corresponding type. Visit the Reference Manual - Variables for more details.

Declaration

In Go, type declarations come after the variable name. The var keyword is used for variable declaration, with the format var variableName typeName. Variable names must follow the naming rules for identifiers.

go
var intNum int
var str string
var char byte

When declaring multiple variables of the same type, you can write the type only once:

go
var numA, numB, numC int

When declaring multiple variables of different types, you can use parentheses to wrap them, and there can be multiple ().

go
var (
  name    string
  age     int
  address string
)

var (
  school string
  class int
)

If a variable is declared without assignment, the value stored in the variable is the zero value of the corresponding type.

Assignment

The assignment operator = is used. For example:

go
var name string
name = "jack"

You can also assign directly when declaring:

go
var name string = "jack"

Or like this:

go
var name string
var age int
name, age = "jack", 1

The second method requires specifying the type each time. You can use the official syntactic sugar: short variable initialization, which omits the var keyword and the trailing type. The specific type is inferred by the compiler.

go
name := "jack" // variable of type string

Although you don't need to specify the type, subsequent assignments must keep the type consistent. The following code cannot compile:

a := 1
a = "1"

It should also be noted that short variable initialization cannot use nil because nil does not belong to any type, and the compiler cannot infer its type.

go
name := nil // cannot compile

Short variable declarations can be batch initialized:

go
name, age := "jack", 1

The short variable declaration method cannot be used on an already existing variable:

go
// Wrong example
var a int
a := 1

// Wrong example
a := 1
a := 2

However, there is one exception: when assigning to an old variable while declaring a new variable at the same time:

go
a := 1
a, b := 2, 2

This code can compile. Variable a is reassigned, while b is newly declared.

In Go, there is a rule that all variables declared inside a function must be used. For example, the code below only declares a variable but does not use it:

go
func main() {
  a := 1
}

It will report a compile-time error, indicating that the variable was declared but not used:

a declared and not used

This rule only applies to variables inside functions. For package-level variables outside functions, there is no such restriction. The following code can compile:

go
var a = 1

func main() {

}

Anonymous

You can use an underscore to indicate that a certain variable is not needed:

go
Open(name string) (*File, error)

For example, the os.Open function has two return values. If we only want the first one and not the second, you can write it as follows:

go
file, _ := os.Open("readme.txt")

Unused variables cannot compile. When you don't need a certain variable, you can use underscore _ instead.

Swap

In Go, if you want to swap the values of two variables, you don't need to use pointers. You can swap directly using the assignment operator. The syntax looks very intuitive:

go
num1, num2 := 25, 36
num1, num2 = num2, num1

The same applies to three variables:

go
num1, num2, num3 := 25, 36, 49
num1, num2, num3  = num3, num2, num1

Consider the following code snippet, which is part of calculating the Fibonacci sequence. What are the values of the three variables after calculation?

go
a, b, c := 0, 1, 1
a, b, c = b, c, a+b

The answer is:

1 1 1

You might wonder why it's not:

1 1 2

Why was a assigned the value of b, but the result of a+b is still 1? When Go performs multiple variable assignment operations, it calculates the values first and then assigns them, not from left to right.

go
a, b, c = b, c, a+b

You might think it would be expanded to:

go
a = b
b = c
c = a + b

But actually, it calculates the values of a, b, and c first and then assigns them, which is equivalent to:

go
a, b, c = 1, 1, 0+1

When function calls are involved, this effect is more obvious. We have a function sum that returns the sum of two numbers:

go
func sum(a, b int) int {
  return a + b
}

Performing two-number addition through the function:

go
a, b, c := 0, 1, 1
a, b, c = b, c, sum(a, b)

The result does not change. When calculating the return value of the sum function, its input parameters are still 0 and 1:

1 1 1

So the code should be written separately:

go
a, b = b, c
c = a + b

Comparison

There is a major prerequisite for comparing variables: their types must be the same. Go does not have implicit type conversion. The following code cannot compile:

go
func main() {
  var a uint64
  var b int64
  fmt.Println(a == b)
}

The compiler will tell you that the types do not match:

invalid operation: a == b (mismatched types uint64 and int64)

Therefore, you must use explicit type conversion:

go
func main() {
  var a uint64
  var b int64
  fmt.Println(int64(a) == b)
}

Before generics were available, the early Go built-in min and max functions only supported floating-point numbers. In version 1.21, Go finally rewrote these built-in functions using generics. Now you can use the min function to compare minimum values:

go
minVal := min(1, 2, -1, 1.2)

Use the max function to compare maximum values:

go
maxVal := max(100, 22, -1, 1.12)

Their parameters support all comparable types. The comparable types in Go are:

  • Booleans
  • Numbers
  • Strings
  • Pointers
  • Channels (only supports checking equality)
  • Arrays of comparable types (slices are not comparable) (only supports checking equality) (only supports comparison between arrays of the same length, because array length is also part of the type, and different types cannot be compared)
  • Structs where all field types are comparable (only supports checking equality)

In addition, you can also import the standard library cmp for comparison, but it only supports ordered type parameters. In Go, the built-in ordered types are only numbers and strings.

go
import "cmp"

func main() {
  cmp.Compare(1, 2)
  cmp.Less(1, 2)
}

Code Blocks

Inside a function, you can create a code block using curly braces. The variable scopes between code blocks are independent of each other. For example:

go
func main() {
  a := 1

  {
    a := 2
    fmt.Println(a)
  }

  {
    a := 3
    fmt.Println(a)
  }
  fmt.Println(a)
}

Output:

2
3
1

Variables between blocks are independent of each other, not interfered with, cannot be accessed, but can be affected by the parent block.

go
func main() {
  a := 1

  {
    a := 2
    fmt.Println(a)
  }

  {
    fmt.Println(a)
  }
  fmt.Println(a)
}

Output:

2
1
1

Golang by www.golangdev.cn edit