Welcome To Golang By Example

Variables in Go (Golang)

This is the chapter 6 of the golang comprehensive tutorial series. Refer to this link for other chapters of the series – Golang Comprehensive Tutorial Series

Next Tutorial – All basic data types
Previous Tutorial – Packages and Modules – Part 2

Now let’s check out the current tutorial. Below is the table of contents for the current tutorial.

What is variable

A variable is the name of a memory location. That memory location may store a value of any type. So each variable has a type associated with it which determines the size and range of that variable and also the operations defined on that variable.

Naming Conventions

Declaring a variable

In GO variables are declared using the var keyword but there are other ways of declaring a variable too as we will see later in this tutorial. Let’s explore different ways of declaring a variable

Single variable declaration without initial value

Below is the format of a single variable declaration without initial value being assigned. First is the var keyword, second is the variable name and third is the variable type.  Also note when the value is not provided , then the variable is initialised with the default value of that type which is also known as zero value of that type. In Go default value or zero value of int is zero

var <variable_name> <type>

See the below example, it declares a var named aaa of type int

package main

import "fmt"

func main() {
    var aaa int
    fmt.Println(aaa)
}

Output: It will print the default value of int which is zero

0

Single variable declaration with initial value

Below is the format of a single variable declaration with initial value being assigned. Everything is same as above, only thing additional is that we assign value to the variable at the end

var <variable_name> <type> = <value>

See below example, it declares a var named aaa of type int and gives a value 8 to it

package main

import "fmt"

func main() {
    var aaa int = 8
    fmt.Println(aaa)
}

Output:

8

Multiple variable declaration without initial value

Below is the format of a multiple variable declaration without initial value being assigned. Please note only variables of same type can be declared together. The type comes at the end

var <name1>, <name2>,….<nameN> <type>

See below example

package main

import "fmt"

func main() {
    var aaa, bbb int
    fmt.Println(aaa)
    fmt.Println(bbb)
}

Output: It will print the default or zero value of int which is zero for both aaa and bbb

0
0

Multiple variable declaration with initial value

Below is the format of a multiple variable declaration with initial value being assigned. Please note only variables of same type can be declared together. The type comes at the end

var <name1>, <name2>, …..,<nameN> <type> = <value1>, <value2>, …..,<valueN>

See below code example. Variable aaa and bbb are given a value of 8 and 9 respectively in a single declaration

package main

import "fmt"

func main() {
    var aaa, bbb int = 8, 9
    fmt.Println(aaa)
    fmt.Println(bbb)
}

Output:

8
9

Declare variables of different types

Below is the format for declaring multiple variables with different types. Value can or cannot be assigned to the variable at that time. Variables for which value is not assigned will get default value of that type. In below example we see three declarations.

package main

import "fmt"

func main() {
    var (
        aaa int
        bbb int    = 8
        ccc string = "a"
    )

    fmt.Println(aaa)
    fmt.Println(bbb)
    fmt.Println(ccc)
}

Output:

0
8
a

Variable Declaration with no type or Type Inference

Variables can also be declared without specifying the type.

The GO compiler based upon the value assigned to the variable will figure out the type. So if the variable has an initial value, then the type can be omitted.  This is also called Type Inference. Below is the format for such declaration

var <varialbe_name> = <value>

Below is the type inference table for basic types int, float, complex numbers, string, boolean, characters. It basically means that if the value is an integer the type of the variable inferred will be int, if the value is a float then type of the variable inferred will be float64 and so on based upon below table.

Integersint
Floatsfloat64
Complex Numberscomplex128
Stringsstring
Booleansbool
Charactersint32 or rune

For other types such as Array, Pointer, Structure, etc, type Inference will happen based on the value. Let’s see a working example of the above point.  Notice that type of t is correctly inferred as int as the value assigned to it is 123 which is int. Similarly type of u is also correctly inferred as string as the value assigned to it is a string.

Also notice that the type of variable z is inferred correctly as a struct main.sample

package main

import "fmt"

func main() {
    var t = 123      //Type Inferred will be int
    var u = "circle" //Type Inferred will be string
    var v = 5.6      //Type Inferred will be float64
    var w = true     //Type Inferred will be bool
    var x = 'a'      //Type Inferred will be rune
    var y = 3 + 5i   //Type Inferred will be complex128
    var z = sample{name: "test"}  //Type Inferred will be main.Sample

    fmt.Printf("Type: %T Value: %v\n", t, t)
    fmt.Printf("Type: %T Value: %v\n", u, u)
    fmt.Printf("Type: %T Value: %v\n", v, v)
    fmt.Printf("Type: %T Value: %v\n", w, w)
    fmt.Printf("Type: %T Value: %v\n", x, x)
    fmt.Printf("Type: %T Value: %v\n", y, y)
    fmt.Printf("Type: %T Value: %v\n", z, z)
}

type sample struct {
    name string
}

Output:

Type: int Value: 123
Type: string Value: circle
Type: float64 Value: 5.6
Type: bool Value: true
Type: int32 Value: 97
Type: complex128 Value: (3+5i)
Type: main.sample Value: &{test}

Short variable declaration

Go provides another way of declaring variables which is using the := operator. When := operator is used both var keyword and type info can be omitted. Below is the format for such declaration

 := 

Type inference will happen as explained above. Let’s see a working example

package main

import "fmt"

func main() {
    t := 123      //Type Inferred will be int
    u := "circle" //Type Inferred will be string
    v := 5.6      //Type Inferred will be float64
    w := true     //Type Inferred will be bool
    x := 'a'      //Type Inferred will be rune
    y := 3 + 5i   //Type Inferred will be complex128
    z := sample{name: "test"}  //Type Inferred will be main.Sample

    fmt.Printf("Type: %T Value: %v\n", t, t)
    fmt.Printf("Type: %T Value: %v\n", u, u)
    fmt.Printf("Type: %T Value: %v\n", v, v)
    fmt.Printf("Type: %T Value: %v\n", w, w)
    fmt.Printf("Type: %T Value: %v\n", x, x)
    fmt.Printf("Type: %T Value: %v\n", y, y)
    fmt.Printf("Type: %T Value: %v\n", z, z)
}

type sample struct {
    name string
}

Output

Type: int Value: 123
Type: string Value: circle
Type: float64 Value: 5.6
Type: bool Value: true
Type: int32 Value: 97
Type: complex128 Value: (3+5i)
Type: main.sample Value: &{test}

Some points to be noted about the := operator

a := 8
a := 16
a,b := 1, 2
package main

import "fmt"

func main() {
    a, b := 1, 2
    b, c := 3, 4
    fmt.Println(a, b, c)
}

Output:

1, 3, 4

Important Points

a declared but not used
package main

func main() {
    var a = 1
}
package main

import "fmt"

var a = 123

func main() {
    var a = 456
    fmt.Println(a)
}

Output:

456
package main
import (
    "fmt"
    "math"
)
func main() {
    a := 5 + 3
    b := math.Max(4, 5)
    fmt.Println(a)
    fmt.Println(b)
}

Output:

8
5
package main

func main() {
    var aaa int = 1
    aaa = "atest"

    bbb := 1
    bbb = "btest"
}

Output:

cannot use "atest" (type untyped string) as type int in assignment
cannot use "btest" (type untyped string) as type int in assignment

Variable aaa has been assigned a type of int, hence compiler raises error on assigning a value of type string to it. For variable bbb, the type inferred is int, hence it also raises a compiler error on assigning a value of type string to it.

Scope of a Variable (Local and Global Variable)

A variable declaration can be done at the package level or a function level or a block level. Scope of a variable defines where that variable is accessible and also the life of the variable. Golang variables can be divided into two categories based on scope

Local Variable

See below example

Hence below program will raise compiler error

undefined: i
undefined: aaa

Code:

package main

import "fmt"

func main() {
    var aaa = "test"
    fmt.Println(aaa)
    for i := 0; i < 3; i++ {
        fmt.Println(i)
    }
    fmt.Println(i)
}

func testLocal() {
    fmt.Println(aaa)
}

Global Variable

For example in below program variable aaa will be a global variable available throughout main package. It will be available in any function inside main package. Do note that variable name will not be available outside main package as its name starts with a lowercase letter.

package main

import "fmt"

var aaa = "test"

func main() {
    testGlobal()
}

func testGlobal() {
    fmt.Println(aaa)
}

Output:

test

Conclusion

This is all about variables  in golang. Hope you have liked this article. Please share feedback or improvements or mistakes in comments.

Next Tutorial – All basic data types
Previous Tutorial – Packages and Modules – Part 2