1. Type comparison

Type the alias

Using type aliases is a good habit to have to make your code look more understandable and user-friendly. For example, in the source code builtin.go, you can see the use of aliases, type byte = uint8 byte is the alias of uint8; Type rune = int32 Rune is the alias of int32

// Note the correct declaration of the alias
type MyInt1 int
type MyInt2 = int

func main(a) {
    var i int = 0
    var i1 MyInt1 = i / / # 1
    var i2 MyInt2 = i / / # 2
    fmt.Println(i1,i2)
}
Copy the code

Compile failed, MyInt1 is a new type, MyInt2 is an alias, conversion error at #1. Var i1 MyInt1 = MyInt1(I) // #1

Type more

Different types of go cannot be compared. For example, int cannot be compared to string. False cannot be compared with 0.

Structures can only compare for equality, but not for size.

type a struct { // Its variable can be ==! = more
    name string
    age  int
}
type b struct { // Its variable cannot ==! = more
    age int
    m   map[string]string
}
Copy the code

Structs of the same type can be compared. Structs of the same type depend not only on the type of the attribute, but also on the order of the attribute. If all members of a struct can be compared, then the struct can be compared by == or! = to compare whether the two structures are equal or not. In comparison, the two structures are equal one by one if each of the items is equal, otherwise they are not equal;

[2]int [3]int Slices cannot be compared.

2. The constant

Constant addressing

Constants, unlike variables, are allocated memory at runtime. Constants are usually expanded by the compiler during the preprocessing phase and used as instruction data, so they cannot be addressed.

const i = 100
func main(a) {
    fmt.Println(&i, i) // &i compile error
}
Copy the code

iota

Iota is usually used to declare the accumulation of integral values of constants. Remember that IOTA is reset to 0 when the const keyword is present. Iota counts once for every new line of constant declaration in const.

One iota questions

const (
    x = iota
    _
    y
    z = "zz"
    k 
    p = iota
)
const (
    name = "name"
    c    = iota
    d    = iota
)
func main(a)  {
    fmt.Println(x,y,z,k,p)
    fmt.Println(c,d)
}
// 0 2 zz zz 5
/ / 1. 2
Copy the code

Iota question 2

type Direction int
const (
    North Direction = iota
    East
    South
    West
)
func (d Direction) String(a) string {
    return[...].string{"North"."East"."South"."West"}[d]
}
func main(a) {
    fmt.Printf("%d %d /n", North, South)
    fmt.Println(South) // Println automatically prints using strings
}

/ / 0 2
// South
Copy the code

3. Null versus nil

If you declare a variable but do not assign to it, the variable will have a default zero value of type.

bool      -> false                              
numbers -> 0                                 
string    -> ""      

pointers -> nil
slices -> nil
maps -> nil
channels -> nil
functions -> nil
interfaces -> nil
Copy the code

Visible nil can only be assigned to Pointers, chan, func, interface, Map, or slice variables

var p *int
p == nil    // true
*p          // panic: invalid memory address or nil pointer dereference
Copy the code

Pointers represent addresses to memory, and dereferencing a pointer that is nil can cause panic.

A nil questions

type People interface {
    Show()
}

type Student struct{}

func (stu *Student) Show(a) {}

func main(a) {
    var s *Student
    if s == nil {
        fmt.Println("s is nil")}else {
        fmt.Println("s is not nil")}var p People = s
    if p == nil {
        fmt.Println("p is nil")}else {
        fmt.Println("p is not nil")}}// s is nil
// p is not nil
Copy the code

Interface type values are nil if and only if both dynamic values and dynamic types are nil

Nil question 2

func Foo(x interface{}) {
    if x == nil {
        fmt.Println("empty interface")
        return
    }
    fmt.Println("non-empty interface")}func main(a) {
    var x *int = nil
    Foo(x)
}

// non-empty interface
Copy the code