Arrays and Slices
[1], Arrays
1, what is an array
array
- The array needs to beSame type of dataset (math.)
- Arrays are required to define the size
- Once an array is defined the size cannot be changed.
package main
import "fmt"
// Arrays
// An array is no different from any other variable definition, except that it's a set of numbers that need to be given a size [6]int [10]string
// An array is an ==ordered ==collection of data of the same type, with subscripts to retrieve the corresponding data.
// Several characteristics of an array:
// 1, the length must be determined, if not, it is not an array, the size can not be changed
// 2, the elements must be phase, the same type can not be mixed with more than one type, [any is also a type, you can store any type of data].
// 3, the type of the elements in the array, can be all the types we learned, int, string, float, bool, array, slice, map
func main() {
// Derived data types
// Definition of an array: [array size size] Type of the variable We define a collection of numbers of this type, of size
// The default value is 00000
var arr1 [5]int
arr1[0] = 1
arr1[1] = 2
arr1[2] = 3
arr1[3] = 4
arr1[4] = 5
(arr1)
for i := 0; i < len(arr1); i++ {
("%d\n", arr1[i])
}
// Common methods in arrays len() gets the length of the array cap() gets the capacity of the array
("Length of array: ", len(arr1)) // length of array: 5
("Capacity of the array: ", cap(arr1)) // Capacity of the array: 5
// Modify the value of the array
arr1[1] = 100
(arr1)
}
2. Initialize the array
package main
import "fmt"
func main() {
// Initialize the array by assigning values
var arr1 = [5]int{0, 1, 2, 3, 4}
(arr1)
// Quick assignment
arr2 := [5]int{0, 1, 2, 3, 4}
(arr2)
// Accepts user input as an array.
// ... represents the length of the array
// Go's compiler automatically assigns a value to ... based on the length of the array. to automatically derive the length of the array.
// Note that the array here is not infinite, but also fixed in size, depending on the number of elements in the array.
arr3 := [...] int{0, 1, 2, 3, 4, 5, 5, 5, 6, 7, 8, 9}
(len(arr3), arr3)
// Default array values, assigning values to only a few of the elements.
var arr4 [10]int
(arr4)
arr4[6] = 600
arr4[5] = 500
(arr4)
}
3, traversing the array elements
package main
import "fmt"
/*)
1, directly through the subscript to get the element arr[index]
2、 0-len i++ You can use a for loop to combine the array subscripts for traversal
3、for range:range (new)
*/
func main() {
arr3 := [...] int{0, 1, 2, 3, 4, 5, 5}
for i := 0; i < len(arr3); i++ {
(arr3[i])
}
// goland shortcut array.for, future loop arrays, slicing many times use for range
// for subscript, value of subscript range target array slice
// That's just iterating over the array. Returns two values, index and value.
// Note that if you're receiving only one value, you're returning the subscript of the array.
// Note that if you only receive two values, you return the subscript and the value of the subscript.
for _, value := range arr3 {
("value:", value)
}
}
4. Arrays are value types
package main
import "fmt"
// Arrays are value types: all assignments that modify the value of an object do not affect the original object.
func main() {
arr3 := [...] int{0, 1, 2, 3, 4, 5, 5}
arr4 := [...] string{"111", "222"}
("%T\n", arr3)
("%T\n", arr4)
arr5 := arr3
arr3[6] = 7
("%T\n", arr3)
(arr5) // Arrays are value passed, copying a new memory space
}
5. Array sorting
arr := [6]int{1,2,3,4,5,0}
// Ascending ASC: smallest to largest 0,1,2,3,4,5 A-Z 00:00-24:00
// Descending DESC : ascending 5,4,3,2,1,0
// bubbling sort
package main
import "fmt"
func main() {
arr1 := [...]int{1, 2, 3, 4, 5, 0, 77, 95, 11, 23, 54, 88, 33, 10, 23, 19}
//var temp int = 0
for i := 0; i < len(arr1); i++ {
for j := i + 1; j < len(arr1); j++ {
if arr1[i] > arr1[j] {
arr1[i], arr1[j] = arr1[j], arr1[i]
}
}
}
(arr1)
}
6. Multi-dimensional arrays
One-dimensional array: Linear, a set of numbers.
2D Arrays: Tabular, Array over Array
3D arrays: three-dimensional spatial, arrays over arrays over arrays
xxxx dimensional arrays: xxx, array sets of arrays sets of arrays .....
package main
import "fmt"
func main() {
// Define a multidimensional array of two dimensions.
arr := [3][4]int{
{0, 1, 2, 3}, // arr[0] // array
{4, 5, 6, 7}, // arr[1]
{8, 9, 10, 11}, // arr[2]
}
// A two-dimensional array, a one-dimensional array holds the array
(arr[0])
// To get a value in this 2D array, find the coordinates of the corresponding 1D array, arr[0] as a whole
(arr[0][1])
("------------------")
// How to iterate through a two-dimensional array
for i := 0; i < len(arr); i++ {
for j := 0; j < len(arr[i]); j++ {
(arr[i][j])
}
}
// for range
for i, v := range arr {
(i, v)
}
}
[2], Sliced
Go language slices are an abstraction of arrays.
The length of Go arrays is immutable, which makes such collections less suitable in certain scenariosThe Go program provides a flexible, powerful, and easy to useBuilt-in type Slices ("dynamic arrays"), as opposed to arraysThe length of the slice is not fixed and elements can be appended, which may increase the capacity of the slice.。
Slicing is a convenient, flexible and powerful wrapper thatThe slices themselves don't have any data, they are just references to existing arrays.
Slices are compared to arrays ofNo need to set the length, no need to set the value in [], relatively free
Conceptually, a slice is like a structure that contains three elements:
- Pointer: Points to the start of the slice in the array.
- Length: the length of the slice
- Maximum length: the length from the beginning of the slice to the end of the array.
1. Definition of slicing
package main
import "fmt"
func main() {
var s1 []int // variable length, length is variable
(s1)
// Slicing empty judgment, in initializing slices, defaults to nil
if s1 == nil {
("s1 is empty")
}
("%T\n", s1)
s2 := []int{1, 2, 3, 4}
(s2[2])
}
2. make to create slices
package main
import "fmt"
func main() {
// make()
// make([]Type,length,capacity) // create a slice, length, capacity
s1 := make([]int, 5, 10)
(s1)
(len(s1), cap(s1))
// Think: with a capacity of 10 and a length of 5, can I store 6 pieces of data?
s1[0] = 10
s1[7] = 200 // index out of range [7] with length 5
// The bottom of the slice is still an array [0 0 0 0 0 0 0] [2000].
// Going straight to assignment doesn't work, don't think in terms of inertia
(s1)
// Slice expansion
}
3、Slice expansion
package main
import "fmt"
func main() {
s1 := make([]int, 0, 5)
// slice and expand, append()
s1 = append(s1, 1, 2)
(s1)
s2 := []int{100, 200, 300, 400}
// Introduce another slice for slice expansion.
// slice = append(slice, anotherSlice...)
// ... Variable parameters ... .xxx
// [...] Change the size of the array according to the length of the definition
// anotherSlice... , slice... Deconstructed to get all the elements in slice directly
s1 = append(s1, s2...)
(s1)
}
4, traversing the slice
package main
import "fmt"
func main() {
s1 := make([]int, 0, 5)
(s1)
// slice and expand, append()
s1 = append(s1, 1, 2)
(s1)
// Question: the capacity is only 5, can we put more than 5? Yes, slices are automatically expanded.
s1 = append(s1, 2, 3, 3, 4, 4, 4, 5, 6, 6, 7, 7)
(s1)
// Introduce another slice for slice augmentation.
// new: deconstruct slice... . to extract all the elements of the slice.
s2 := []int{100, 200, 300, 400}
// slice = append(slice, anotherSlice...)
// ... Variable arguments ... .xxx
// [...] Change the size of the array according to the length of the definition
// anotherSlice... , slice... Deconstructs the slice to get all the elements in the slice directly
// s2... = {100,200,300,400}
s1 = append(s1, s2...)
// Iterate through the slice
for i := 0; i < len(s1); i++ {
(s1[i])
}
for i := range s1 {
(s1[i])
}
}
5. Memory analysis for expansion
// 1. Each slice references an underlying array
// 2. The slice itself does not store any data, it is the underlying array that stores it, so modifying the slice also modifies the data in the array.
// 3. When adding data to a slice, if it doesn't exceed the capacity, add it directly, and if it exceeds that capacity, it will automatically expand the capacity exponentially. copy
// - Principles of Analyzing Programs
// - see source code
//
// 4. Once a slice is expanded, it is redirected to a new underlying array.
package main
import "fmt"
func main() {
s2 := []int{1, 2, 3}
(len(s2), cap(s2))
("%p\n", s2)
s2 = append(s2, 4, 5)
(len(s2), cap(s2))
("%p\n", s2)
s2 = append(s2, 4, 5)
(len(s2), cap(s2))
("%p\n", s2)
s2 = append(s2, 4, 5)
(len(s2), cap(s2))
("%p\n", s2)
s2 = append(s2, 4, 5)
(len(s2), cap(s2))
("%p\n", s2)
s2 = append(s2, 4, 5)
(len(s2), cap(s2))
("%p\n", s2)
s2 = append(s2, 4, 5)
(len(s2), cap(s2))
("%p\n", s2)
/* 3 3
0xc000126078
5 6
0xc000144030
7 12
0xc000102060
9 12
0xc000102060
11 12
0xc000102060
13 24
0xc000152000
15 24
0xc000152000
*/
}
A concrete implementation of slice expansion
The main methods used are make and copy.
package main
import "fmt"
func main() {
s2 := []int{1, 2, 3}
("len:%d,cap:%d,%v\n", len(s2), cap(s2), s2)
s3 := make([]int, len(s2), cap(s2)*2)
copy(s3, s2)
("len:%d,cap:%d,%v\n", len(s3), cap(s3), s3)
}
6, the use of arrays to create slices
package main
import "fmt"
func main() {
arr := [10]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
// Array slicing
// Create slices through the array
s1 := arr[:5] // 1-5
s2 := arr[3:8] // 4-8
s3 := arr[5:] // 6-10
s4 := arr[:] // 0-10
(s1)
(s2)
(s3)
(s4)
// Check capacity and length
// The length of the slice is the number of elements in the intercepted array, and the capacity of the slice is the number of elements from the start of the intercepted array to the end of the array.
("s1 len:%d, cap:%d\n", len(s1), cap(s1)) // s1 len:5, cap:10
("s2 len:%d, cap:%d\n", len(s2), cap(s2)) // s2 len:5, cap:7
("s3 len:%d, cap:%d\n", len(s3), cap(s3)) // s3 len:5, cap:5
("s4 len:%d, cap:%d\n", len(s4), cap(s4)) // s4 len:10, cap:10
// The memory address of the slice is the address at the beginning of the array cap(slice) = len(array) and they have the same memory address
("%p,%p\n", s1, &arr) // 0xc000016230,0xc000016230
("%p,%p\n", s2, &arr[3]) // 0xc000016248,0xc000016248
("%p,%p\n", s2, &arr[3]) // 0xc000016248,0xc000016248
("%p,%p\n", s3, &arr[5]) // 0xc000016258,0xc000016258
("%p,%p\n", s4, &arr[0]) // 0xc000016230,0xc000016230
// Modify the contents of the array, and the slice changes (cut: slices don't hold data - > the underlying array)
arr[2] = 100
(arr) // [1 2 100 4 5 6 7 8 9 10]
(s1) // [1 2 100 4 5]
(s2) // [4 5 6 7 8]
(s3) // [6 7 8 9 10]
(s4) // [1 2 100 4 5 6 7 8 9 10]
("--------------------------------------------")
// Modify the contents of the slice, and notice that the array changes with it. (Essentially: all that is modified is the underlying array)
s2[2] = 80
(arr) // [1 2 100 4 5 80 7 8 9 10]
(s1) // [1 2 100 4 5]
(s2) // [4 5 80 7 8]
(s3) // [80 7 8 9 10]
(s4) // [1 2 100 4 5 80 7 8 9 10]
("--------------------------------------------")
// Slicing and expanding, if the capacity exceeds the cap, it doesn't affect the original array, so s1 now points to a new array
s1 = append(s1, 11, 12, 13, 14, 15, 16)
(arr) // [1 2 100 4 5 80 7 8 9 10]
("s1:%p,arr:%p\n", s1, &arr) // s1:0xc0000d4000,arr:0xc0000ac0f0
}
7. Slices: reference types
package main
import "fmt"
func main() {
arr1 := [3]int{1, 2, 3}
arr2 := arr1
("arr1:", arr1, "arr2:", arr2)
("arr1:%p,arr2:%p\n", &arr1, &arr2) // arr1:0xc0000aa078,arr2:0xc0000aa090
arr1[1] = 10
("arr1:", arr1, "arr2:", arr2) // [3 4 5] [3 4 5]
("---------------------------------")
s1 := make([]int, 0, 5)
s1 = append(s1, 3, 4, 5)
s2 := s1
(s1, s2)
("s1:%p,s2:%p\n", s1, s2) //s1:0xc0000c8030,s2:0xc0000c8030
s1[1] = 30
(s1, s2) // [3 30 5] [3 30 5]
}
8, deep copy, shallow copy
Deep copy: the copy is the data itself
- Data of value types, which are all deep copies by default, array, int, float, string, bool, struct ....
Shallow copy: the copy is the address of the data and will result in multiple variables pointing to the same block of memory.
- Data of reference type: slice, map
- Because slices are references to class data, direct copies are made to this address
Slicing how to implement deep copy copy
package main
import "fmt"
func main() {
// Copy the data from the original slice into the new slice.
s1 := []int{1, 2, 3, 4}
s2 := make([]int, 0) // len:0 cap:0
for i := 0; i < len(s1); i++ {
s2 = append(s2, s1[i])
}
(s1, s2)
("%p,%p\n", s1, s2)
s1[2] = 200
(s1, s2)
}
9. Parameter passing in functions
The data is categorized according to its storage characteristics:
- Data of value type: operates on the data itself, int , string, bool, float64, array...
- Data of reference type: the operation is the address of the data slice, map, chan....
value transmission
pass by reference
package main
import "fmt"
func main() {
// value transmission
arr := [3]int{1, 2, 3}
(arr)
update(arr)
(arr)
// pass by reference
s1 := []int{4, 5, 6}
(s1)
update_s(s1)
(s1)
}
func update(arr [3]int) {
(arr)
arr[1] = 100
(arr)
}
func update_s(s1 []int) {
(s1)
s1[1] = 20
(s1)
}