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