golang learning notes Part 2: 9 Arrays and slices

Posted by nec9716 on Wed, 09 Feb 2022 19:12:01 +0100

golang learning notes Part 2: 9 Arrays and slices

18. Array

1) Array definition: store multiple data of the same type. In go language, array is the value type var array name [array size] data type
var a [5]int var b [3]int = [3]int{1,2,3} var c = [3]int{1,2,3} var d = [...] int {1,2,3} / /... Represents the traversal of the array for the system to judge the data size
Method 1: General traversal method 2: for range structure traversal for index, value: = range array01 {...}
Index is the subscript of the array and value is the value corresponding to the subscript. These two variables are local variables only in the for loop. They can be used when subscripts are not required_ Replace the names of index, index and value, which can be customized. 3) precautions and details

  • The data types in the array are the same and cannot be mixed. They can be value types or reference types
  • The length of the array is fixed and cannot be changed dynamically
  • var arr []int is actually a slice
  • After the array is created, if there is no assignment, there is a default value of type
  • The array of go is a value type. By default, it is value transfer, so the value will be copied and the arrays will not affect each other
  • If you want to modify the original array in other functions, you can use reference passing (pointer mode). When the amount of array data is very large, the efficiency of value copying is much lower than reference passing, because only one memory address is copied
  • Length is a part of the array type. When passing function parameters, the length of the array needs to be considered

Array basis

package main

import "fmt"

func test01(arr [3]int) { //[3]int [4]int is not a data type here because the length is different
	arr[0] = 88
	fmt.Println("in func test01", &arr[0], arr)
}

func test02(arr *[3]int) {
	(*arr)[0] = 99 //Use of pointers to arrays
	fmt.Printf("arr Address of pointer %p\n", &arr)
	fmt.Println("in func test02", &arr[0], *arr)
}

func main() {
	// var score [6]float64
	// fmt.Printf("address of array% P \ n", & score)
	// fmt.Printf("address of the first element of the array% P \ n", & score [0])
	// for i := 0; i < len(score); i++ {
	// 	fmt.Printf("please enter element% d", i+1)
	// 	fmt.Scanln(&score[i])
	// }

	// for i := 0; i < len(score); i++ {
	// 	fmt.Printf("score[%d]=%v\n", i, score[i])
	// }

	// var b [3]int = [3]int{1, 2, 3}
	// var c = [3]int{1, 2, 3}
	// var d = [...]int{1, 2, 3}             //... It means to let the system judge the data size and fix the writing method
	// e := [...]int{1: 123, 2: 111, 0: 333} / / specify subscript assignment and type derivation
	// fmt.Println("b", b)
	// fmt.Println("c", c)
	// fmt.Println("d", d)
	// fmt.Println("e", e)

	// for i, v := range e {
	// 	fmt.Println(i, v)
	// }

	arr := [3]int{11, 22, 33} //If [4]int is defined here, an error will be reported when the parameter is passed in
	test01(arr)
	fmt.Println("in func main", &arr[0], arr) //Because it is a value type, arr[0] = 11 instead of 88. You can see that the two arr[0] addresses are also different. The functions test and main generate independent memory space for the ARR array separately

	test02(&arr)
	fmt.Println("in func main", &arr[0], arr) //You can see that after the pointer is referenced, the arr array value in the functions test and main is the same as the memory address
}

Array exercise

package main

import (
	"fmt"
	"math/rand"
	"time"
)

func exe01() {
	//Create an array of byte type, place A-Z, and use for to access all elements and print
	var myChars [26]byte
	for i := 0; i < 26; i++ {
		myChars[i] = 'A' + byte(i)
	}

	for i := 0; i < 26; i++ {
		fmt.Printf("%c ", myChars[i])
	}
}

func exe02() {
	//Request the maximum value of an array and get the corresponding subscript
	//thinking
	//1. Declare an array and fill in the contents
	//2. Assume that the first element is the maximum value and the subscript is 0
	//3. Compare the assumed first element with each subsequent element loop, and exchange if there is a larger number
	intArr := [...]int{1, -1, 33, 5, 15, 111}
	maxVal := intArr[0]
	maxValIndex := 0
	for i := 1; i < len(intArr); i++ {
		if maxVal < intArr[i] {
			maxVal = intArr[i]
			maxValIndex = i
		}
	}
	fmt.Printf("maxVal=%v maxValIndex=%v \n", maxVal, maxValIndex)
}

func exe03() {
	//Request the sum and average value of an array, and use for range
	intArr2 := [...]int{1, -1, 33, 5, 15}
	sum := 0
	for _, val := range intArr2 {
		sum += val
	}
	fmt.Printf("Sum of arrays=%v,average value=%v \n", sum, float32(sum)/float32(len(intArr2))) //go operation, the result of int division is an integer, and the floating-point type needs to be converted
}

func exe04() {
	//Generate 5 numbers randomly and print them reversely
	//thinking
	//1. Use Rand The intn() function generates a random number and puts it into the array
	//2. Reverse printing: exchange times = array size / 2, the first and last exchange, the second and penultimate exchange, and so on
	var intArr3 [33]int
	arrlen := len(intArr3)
	rand.Seed(time.Now().UnixNano()) //Generating random seeds with nanosecond timestamp
	for i := 0; i < arrlen; i++ {
		intArr3[i] = rand.Intn(100)
	}
	fmt.Printf("Pre swap array %v\n", intArr3)
	for i := 0; i < arrlen/2; i++ {
		tmp := intArr3[i]                //The ith temporary variable
		intArr3[i] = intArr3[arrlen-i-1] //The penultimate i is assigned to the i, and the array subscript starts from 0. Therefore, an array of - 1 and 5 elements is required, and the last subscript is 4
		intArr3[arrlen-i-1] = tmp        //The temporary variable (the ith) is assigned to the penultimate i
	}
	fmt.Printf("Array after exchange %v\n", intArr3)
}

func main() {
	// exe01()
	// exe02()
	// exe03()
	exe04()
}

19. Slice

1) A slice is a reference to an array, so a slice is a reference type; The length of slices can be changed; The use of slice is similar to that of array. 2) the basic syntax of slice definition: VAR slice name [] type: var a []int 3) the use of slice: 1. Define a slice and reference an array that has been created;
Method 2: create slices through make: var slice []int = make([]type,len,[cap]) //cap optional method 3: define a slice and directly specify a specific array. The principle is similar to that of make 4) the slice traversal method is the same as that of array:
Abbreviations of general for and for range 5) reference arrays: X to end arr[x:end], start to x arr[start:x], all arr [:]
6) Slice can continue to slice. 7)append built-in function can dynamically append slices. When the capacity is insufficient, it will dynamically expand the capacity and generate a new underlying array. 8) slice can be appended. The fixed writing method is slice = append(slice,slice...), and array 9 cannot be appended)
For the copy operation of slice, the built-in function copy is used. After copying, it is still the slice type copy(b,a)
a. b is the slice type. Copy each element of a to the corresponding position of b. the other space of b remains unchanged, but the slice of b changes; Only copy values, and the relative space is independent; When the length of a is greater than b, the elements that can be accommodated 10)string and slice are copied from front to back
The bottom layer of string is a byte array, so it can be sliced. String is immutable and cannot be modified through str[0]='a '; You can modify the converted slice by changing string - > [] byte or [] run

Slice basis

package main

import (
	"fmt"
)

func demo1() {
	var intArr [5]int = [...]int{1, 2, 3, 4, 5}
	slice := intArr[1:3]
	fmt.Println("The value, length and capacity of the slice are:\n", slice, len(slice), cap(slice))
	fmt.Printf("%p %p \n", &intArr[1], &slice[0]) //The addresses of array and slice are the same
	//The essence of slicing is a struct: memory address len cap

	slice[0] = 22 //Modifying the slice is actually modifying the referenced array
	fmt.Println(intArr, slice)
	slice = append(slice, 11)
	fmt.Println("The value, length and capacity of the slice are:\n", slice, len(slice), cap(slice))
	slice = append(slice, 22)
	fmt.Printf("%p %p \n", &intArr[1], &slice[0])
	fmt.Println("The value, length and capacity of the slice are:\n", slice, len(slice), cap(slice))
	slice = append(slice, 33)
	fmt.Println("The value, length and capacity of the slice are:\n", slice, len(slice), cap(slice))
	//Capacity is dynamically adjusted
	fmt.Printf("%p %p \n", &intArr[1], &slice[0])
	//After dynamic expansion, a new underlying array is generated, and the memory address is different
	slice[0] = 222 //At this time, the original array will not change
	fmt.Println(intArr, slice)
}

func demo2() {
	//There are two other ways to create slices. The underlying array is not visible. slice operation is used
	var slice1 []int = []int{1, 2, 3}
	var slice2 []int = make([]int, 2, 6)
	fmt.Println(slice1, slice2)
	//The traversal method is the same as array
	for i := 0; i < len(slice1); i++ {
		fmt.Println(slice1[i])
	}

	for i, v := range slice1 {
		fmt.Println(i, v)
	}
}

func demo3() {
	var a []int = []int{1, 2, 3, 4, 5}
	var b = make([]int, 10)
	copy(b, a)
	fmt.Println(a, b)
}

func demo4() {
	str := "you are so beatuful"
	slice := str[4:7]
	fmt.Println(slice)
	// str[1] = '1' / / compilation error
	slice2 := []byte(str)
	slice2[0] = 'x' //No error will be reported for such modification
	str = string(slice2)
	fmt.Println(str) //byte type cannot process Chinese, because a Chinese has 3 bytes, and run is processed according to characters, which is compatible with Chinese characters
}

func main() {
	demo4()
}

Slicing exercise

package main

import "fmt"

//Write a function to put the Fibonacci sequence into the slice
func finb(n int) []uint64 {
	//thinking
	//Fibonacci sequence: 1,2,3,5,8
	//Define a function that returns the slice
	slice := make([]uint64, n)
	slice[0] = 1
	slice[1] = 1
	for i := 2; i < n; i++ {
		slice[i] = slice[i-1] + slice[i-2]
	}
	return slice
}

func main() {
	fnb := finb(10)
	fmt.Println(fnb)
}

Topics: Go data structure