Types


Types in Go are divided into 2 categories: named and unnamed. Besides predeclared types (such as int, rune, etc), you can also define named type yourself. E.g.:

type mySlice []int

Unnamed types are defined by type literal. I.e., []int is an unnamed type.

According to Go spec, there is an underlying type of every type:

Each type T has an underlying type: If T is one of the predeclared boolean, numeric, or string types, or a type literal, the corresponding underlying type is T itself. Otherwise, T's underlying type is the underlying type of the type to which T refers in its type declaration.

So, in above example, both named type mySlice and unnamed type []int have the same underlying type: []int.

Go has strict rules of assigning values of variables. For example:

package main

import "fmt"

type mySlice1 []int
type mySlice2 []int

func main() {
    var s1 mySlice1
    var s2 mySlice2 = s1

    fmt.Println(s1, s2)
}

The compilation will complain the following error:

cannot use s1 (type mySlice1) as type mySlice2 in assignment

Although the underlying type of s1 and s2 are same: []int, but they belong to 2 different named types (mySlice1 and mySlice2), so they can't assign values each other. But if you modify s2's type to []int, the compilation will be OK:

package main

import "fmt"

type mySlice1 []int

func main() {
    var s1 mySlice1
    var s2 []int = s1

    fmt.Println(s1, s2)
}

The magic behind it is one rule of assignability:

x's type V and T have identical underlying types and at least one of V or T is not a named type.

References:
Go spec;
Learning Go - Types;
Golang pop quiz.

results matching ""

    No results matching ""