1, Array
An array is a collection of data of the same type. Each data contained in the array is called an array element. This type can be the original type of meaning, such as int, string, etc., or a user-defined type. The number of elements contained in an array is called the length of the array. In Golang, array is a data type with a fixed length, and the length of array is a part of the type, that is, [5]int and [10]int are two different types. Another feature of array in Golang is the continuity of memory occupation, that is, the elements in the array are allocated to continuous memory addresses, so the speed of index group elements is very fast.
The type corresponding to the array is slice. Slice is a dynamic sequence that can grow and shrink, and its function is more flexible. However, if you want to understand the working principle of slice, you need to understand the array first, so this section mainly explains the use of array.
array define
var Array variable name [Number of elements] T
Examples
// The length of the array is part of the type var arr1 [3]int var arr2 [4]string fmt.Printf("%T, %T \n", arr1, arr2) // The first method of array initialization var arr3 [3]int arr3[0] = 1 arr3[1] = 2 arr3[2] = 3 fmt.Println(arr3) // The second method is to initialize the array var arr4 = [4]int {10, 20, 30, 40} fmt.Println(arr4) // The third array initialization method automatically infers the array length var arr5 = [...]int{1, 2} fmt.Println(arr5) // The fourth way to initialize an array is to specify a subscript a := [...]int{1:1, 3:5} fmt.Println(a)
Traversal array
Method 1
// The fourth way to initialize an array is to specify a subscript a := [...]int{1:1, 3:5} for i := 0; i < len(a); i++ { fmt.Print(a[i], " ") }
Method 2
// The fourth way to initialize an array is to specify a subscript a := [...]int{1:1, 3:5} for _, value := range a { fmt.Print(value, " ") }
Value type of array
Array is a value type. Assignment and reference will assign the entire array, so changing the value of the copy will not change its own value
// array var array1 = [...]int {1, 2, 3} array2 := array1 array2[0] = 3 fmt.Println(array1, array2)
For example, in the above code, after we assign values to the array, when we change the values in the array, we find that the results are as follows
[1 2 3] [3 2 3]
This shows that the array in golang is a value type, not a reference data type like java
Slice definition (reference type)
In golang, the definition of slice is similar to that of array, but it should be noted that slice is a reference data type, as shown below
// Slice definition var array3 = []int{1,2,3} array4 := array3 array4[0] = 3 fmt.Println(array3, array4)
We change the first slice element and see the final effect
[3 2 3] [3 2 3]
Two dimensional array
Go language supports multi-dimensional arrays. Here we take two-dimensional arrays as an example (arrays are nested):
var Array variable name [Number of elements][Number of elements] T
Examples
// Two dimensional array var array5 = [2][2]int{{1,2},{2,3}} fmt.Println(array5)
Array traversal
Traversal of two-dimensional data group
// Two dimensional array var array5 = [2][2]int{{1,2},{2,3}} for i := 0; i < len(array5); i++ { for j := 0; j < len(array5[0]); j++ { fmt.Println(array5[i][j]) } }
Traversal mode 2
for _, item := range array5 { for _, item2 := range item { fmt.Println(item2) } }
Type derivation
In addition, we can also use type derivation when creating arrays, but we can only use one
// Two dimensional array (correct writing) var array5 = [...][2]int{{1,2},{2,3}}
Wrong writing
// Two dimensional array var array5 = [2][...]int{{1,2},{2,3}}
Complete code
package main import "fmt" func main() { // The length of the array is part of the type var arr1 [3]int var arr2 [4]string fmt.Printf("%T, %T \n", arr1, arr2) // The first method of array initialization var arr3 [3]int arr3[0] = 1 arr3[1] = 2 arr3[2] = 3 fmt.Println(arr3) // The second is the violation of initializing arrays var arr4 = [4]int {10, 20, 30, 40} fmt.Println(arr4) // The third array initialization method automatically infers the array length var arr5 = [...]int{1, 2} fmt.Println(arr5) // The fourth way to initialize an array is to specify a subscript a := [...]int{1:1, 3:5} fmt.Println(a) for i := 0; i < len(a); i++ { fmt.Print(a[i], " ") } for _, value := range a { fmt.Print(value, " ") } fmt.Println() // Value type reference type // Both basic data types and arrays are value types var aa = 10 bb := aa aa = 20 fmt.Println(aa, bb) // array var array1 = [...]int {1, 2, 3} array2 := array1 array2[0] = 3 fmt.Println(array1, array2) // Slice definition var array3 = []int{1,2,3} array4 := array3 array4[0] = 3 fmt.Println(array3, array4) // Two dimensional array var array5 = [...][2]int{{1,2},{2,3}} for i := 0; i < len(array5); i++ { for j := 0; j < len(array5[0]); j++ { fmt.Println(array5[i][j]) } } for _, item := range array5 { for _, item2 := range item { fmt.Println(item2) } } }
2, Slice
Why use slicing
A Slice is a variable length sequence of elements of the same type. It is a layer of encapsulation based on array type.
It is very flexible and supports automatic capacity expansion.
A slice is a reference type whose internal structure contains address, length, and capacity.
The basic syntax for declaring slice types is as follows:
var name [] T
Of which:
- Name: indicates the variable name
- T: Represents the element type in the slice
give an example
// Declare slicing. Removing the length is slicing var slice = []int{1,2,3} fmt.Println(slice)
Understanding of nil
When you declare a variable but haven't assigned a value, golang will automatically assign a default value of zero to your variable. This is the zero value for each type.
- bool: false
- numbers: 0
- string: ""
- pointers: nil
- slices: nil
- maps: nil
- channels: nil
- functions: nil
Nil means null, that is, the default value of array initialization is nil
var slice2 [] int fmt.Println(slice2 == nil)
Operation results
true
Traversal of slices
The traversal of slices is the same as that of arrays
var slice = []int{1,2,3} for i := 0; i < len(slice); i++ { fmt.Print(slice[i], " ") }
Defining slices based on arrays
Since the bottom layer of the slice is an array, we can define the slice based on the array
// Defining slices based on arrays a := [5]int {55,56,57,58,59} // Get all the values of the array and return a slice b := a[:] // Gets the specified slice from the array c := a[1:4] // Get data before subscript 3 (excluding 3) d := a[:3] // Get the data after subscript 3 (including 3) e := a[3:]
Operation results
[55 56 57 58 59] [55 56 57 58 59] [56 57 58] [55 56 57] [58 59]
Similarly, we can not only slice the array, but also slice it in the slice
Length and capacity of slices
The slice has its own length and capacity. We can calculate the length by using the built-in len) function and use the built-in cap ()
Function to find the capacity of the slice.
The length of the slice is the number of elements it contains.
The capacity of a slice is the number from its first element to the end of its underlying array element. The length and capacity of slice s can be obtained by the expressions len (s) and cap (s).
give an example
// Length and capacity s := []int {2,3,5,7,11,13} fmt.Printf("length%d capacity%d\n", len(s), cap(s)) ss := s[2:] fmt.Printf("length%d capacity%d\n", len(ss), cap(ss)) sss := s[2:4] fmt.Printf("length%d capacity%d\n", len(sss), cap(sss))
Operation results
Length 6 capacity 6 Length 4 capacity 4 Length 2 capacity 4
Why is the last capacity different? Because we know that after slicing, SSS = [5,7], so the length of the slice is 2, but because the capacity is from the position of 2 to the end, it is 4
The essence of slicing
The essence of slicing is to encapsulate the underlying array, which contains three information
- Pointer to the underlying array
- Length of slice (len)
- Slice capacity (cap)
Using the make function to construct slices
We create slices based on arrays above. If we need to dynamically create a slice, we need to use the built-in make function. The format is as follows:
make ([]T, size, cap)
Of which:
- T: Element type of slice
- size: the number of elements in the slice
- cap: capacity of slice
give an example:
// The make() function creates a slice fmt.Println() var slices = make([]int, 4, 8) //[0 0 0 0] fmt.Println(slices) // Length: 4, capacity: 8 fmt.Printf("Length:%d, capacity%d", len(slices), cap(slices))
It should be noted that there is no way to expand the slice capacity through subscript in golang. If you need to expand the capacity, you need to use append
slices2 := []int{1,2,3,4} slices2 = append(slices2, 5) fmt.Println(slices2) // Output results [1 2 3 4 5]
You can also merge two slices at the same time
// Merge slices slices3 := []int{6,7,8} slices2 = append(slices2, slices3...) fmt.Println(slices2) // Output results [1 2 3 4 5 6 7 8]
It should be noted that the slice will have a capacity expansion operation. When the elements cannot be stored, the original capacity will be doubled
Use the copy() function to copy slices
As we know earlier, slicing refers to data types
- Value type: when changing the copy of the variable, the variable itself will not be changed
- Reference type: when changing the value of the variable copy, the value of the variable itself will be changed
If we need to change the value of the slice without affecting the original slice, we need to use the copy function
// Slices to be copied var slices4 = []int{1,2,3,4} // Use the make function to create a slice var slices5 = make([]int, len(slices4), len(slices4)) // Copy slice value copy(slices5, slices4) // Modify slice slices5[0] = 4 fmt.Println(slices4) fmt.Println(slices5)
The running result is
[1 2 3 4] [4 2 3 4]
Delete values in slices
There is no special method to delete slice elements in Go language. We can use the characteristics of slice itself to delete elements. The code is as follows
// Delete values in slices var slices6 = []int {0,1,2,3,4,5,6,7,8,9} // Delete value with subscript 1 slices6 = append(slices6[:1], slices6[2:]...) fmt.Println(slices6)
Operation results
[0 2 3 4 5 6 7 8 9]