Array is a contiguous memory, almost all the computer language is an array, but the inside of the Go language array is not commonly used, this is because the array is fixed static, once defined length can’t change, and belong to different types, different lengths of array can’t mutual transformation between assignment, there are many inconvenient to use.

A slice is a dynamic array that can be expanded to increase its length. When the length is constant, it works just like an ordinary array. When the length is different, they are of the same type and can be assigned to each other. The ease of slicing allows arrays to be widely replaced in most applications.

However, you can not look down on the array, in the underlying implementation of slicing, array is the cornerstone of slicing, is the special syntax of slicing hidden internal details, so that users can not directly see the internal hidden array. Slices are just a package of arrays, giving stubborn numbers flexible wings, allowing stones to fly.

Just the above text instructions, the reader must feel confused. Let’s look at a concrete example.

Definition of an array variable

Let’s try it out first by just declaring the type and not assigning an initial value. The compiler assigns the array a “zero” value by default. The zero value of an array is the zero value of all the internal elements.

package main

import "fmt"

func main(a) {
	var a [9]int
	fmt.Println(a)
}

------------
[0 0 0 0 0 0 0 0 0]
Copy the code

Now let’s look at three other variable definitions that have the same effect

package main

import "fmt"

func main(a) {
	var a = [9]int{1.2.3.4.5.6.7.8.9}
	var b [10]int = [10]int{1.2.3.4.5.6.7.8.9.10}
	c := [8]int{1.2.3.4.5.6.7.8}
	fmt.Println(a)
	fmt.Println(b)
	fmt.Println(c)
}

---------------------
[1 2 3 4 5 6 7 8 9]
[1 2 3 4 5 6 7 8 9 10]
[1 2 3 4 5 6 7 8]
Copy the code

Array access

Now let’s use subscripts to do a simple manipulation of the array, which holds the squares of numbers

package main

import "fmt"

func main(a) {
	var squares [9]int
	for i := 0; i < len(squares); i++ {
		squares[i] = (i + 1) * (i + 1)
	}
	fmt.Println(squares)
}

--------------------
[1 4 9 16 25 36 49 64 81]
Copy the code

Subscript out-of-bounds checking for arrays (advanced knowledge)

Notice in the code above that you can use the built-in function len() to get the length of the array directly. The length of the array is determined at compile time, and when we use len() to access the length property of the array, the compiler sneakily replaces it with an integer value.

package main

import "fmt"

func main(a) {
	var a = [5]int{1.2.3.4.5}
	a[101] = 255
	fmt.Println(a)
}

-----
./main.go:7:3: invalid array index 101 (out of bounds for 5-element array)
Copy the code

The above code results show that Go performs compiler checks for array access subscripts that are out of bounds. One important question is, if the subscript is a variable, how does Go check that the subscript is out of bounds? Variables need to be run time to determine whether they are out of bounds. How does Go do this?

package main

import "fmt"

func main(a) {
	var a = [5]int{1.2.3.4.5}
	var b = 101
	a[b] = 255
	fmt.Println(a)
}

------------
panic: runtime error: index out of range

goroutine 1 [running]:
main.main()
	/Users/qianwp/go/src/github.com/pyloque/practice/main.go:8 +0x3d
exit status 2
Copy the code

The answer is that Go inserts subscript traversal logic into compiled code, so subscript access to arrays is less efficient than C’s array access.

Array assignment

Arrays of the same subelement type and length can only be assigned to each other, otherwise they are different array types and cannot be assigned. Assignment of an array is essentially a shallow copy operation; the values of the two array variables assigned are not shared.

package main

import "fmt"

func main(a) {
	var a = [9]int{1.2.3.4.5.6.7.8.9}
	var b [9]int
	b = a
	a[0] = 12345
	fmt.Println(a)
	fmt.Println(b)
}

--------------------------
[12345 2 3 4 5 6 7 8 9]
[1 2 3 4 5 6 7 8 9]
Copy the code

As you can see from the results of the above code, the two arrays do not share internal elements after assignment. If the array size is large, copying is expensive and must be used with care. Now what happens if we try to use arrays of different lengths

package main

import "fmt"

func main(a) {
	var a = [9]int{1.2.3.4.5.6.7.8.9}
	var b [10]int
	b = a
	fmt.Println(b)
}

--------------------------
./main.go:8:4: cannot use a (type [9]int) as type [10]int in assignment
Copy the code

You can see that assignment between arrays of different lengths is forbidden because they are of different types.

Array traversal

In addition to traversing arrays using subscripts, you can also traverse arrays using the range keyword, which provides two forms of traversal.

package main

import "fmt"

func main(a) {
	var a = [5]int{1.2.3.4.5}
	for index := range a {
        fmt.Println(index, a[index])
    }
    for index, value := range a {
		fmt.Println(index, value)
	}
}

------------
0 1
1 2
2 3
3 4
4 5
0 1
1 2
2 3
3 4
4 5
Copy the code

Given the amount of slicing there is, we’ll have a separate section devoted to slicing. The next section will be a very valuable one on the Go language, and you’ll have to struggle to figure out every detail.

Scan the QR code above to read more chapters of Learn Go Quickly