go_day02 arrays and slices

Posted by pmt2k on Wed, 19 Jan 2022 13:48:38 +0100

The array length is part of the array type
Definition of array

//statement
var a1 [3]int
fmt.Print(a1)
//Assignment, note to add length and type
a1 = [3]int{1, 2, 3}
//Method 1 in function
a2 := [3]int{1, 2, 3}
//Method 2 in function
a3 := [...]int{1, 3, 4}
//Method 3 in function, using index
a4 := [5]int{0: 1, 4: 5}
fmt.Print(a1, a2, a3, a4)
//[0 0 0][1 2 3] [1 2 3] [1 3 4] [1 0 0 0 5]

Nothing else. Remember to give the length and type of the array before assigning the value to the array

Define a 2D array

var a [3]int = [3]int{1, 2, 3}
fmt.Print(a)
var b [3][2]int = [3][2]int{
	[2]int{1, 2},
	[2]int{3, 4},
	[2]int{5, 6},
}
fmt.Print(b)
//[1 2 3][[1 2] [3 4] [5 6]]

The length and type of two-dimensional array can not be written during initialization

var b [3][2]int = [3][2]int{
	{1, 2},
	{3, 4},
	{5, 6},
}
fmt.Print(b)

Arrays are in the form of values, not reference types

// array exercise
//1. Sum all elements of the array [1,3,5,7,8]
//Find out the subscripts of the two elements in the array and the specified value. For example, the subscripts with the sum of 8 are (1,2), (0,3)
func main() {
	a := [...]int{1, 3, 5, 7, 8}
	ret := 0
	for _, v := range a {
		ret += v
	}
	fmt.Print(ret)
	s := 8
	for i := 0; i < len(a); i++ {
		for j := i + 1; j < len(a); j++ {
			if a[i]+a[j] == s {
				fmt.Printf("(%d %d)", i, j)
			}
		}
	}

The slice can be of variable length, and the preceding array cannot be of variable length, that is, the number in the length [] is not written..
Slice is a reference type, which points to an underlying array. It has no own value, which is equivalent to a box selection on the array It frames continuous memory

When the slice is declared and not initialized, the slice = = nil is empty (no memory space is opened up.)
len length
cap capacity
There are 3 ways to create slices
1. Create as array
2. Created by array (closed left and open right)

s := []int{1, 2, 4, 5, 6, 7}
a := s[0:4]
fmt.Print(a)
\\ [1 2 4 5]
b := s[:3]
c := s[1:]
d := s[:]

The slice points to an underlying array. Even if the first method is used to create the slice directly, it creates an array first and then returns the slice. Modifying the value of the underlying array will directly modify the value of the slice
The length of the slice is the length of its element
The capacity of the slice is the number of the underlying array from the first element to the last element of the slice
3. Create by making

s1 := make([]int, 5, 10)
fmt.Printf("%v %d %d", s1, len(s1), cap(s1))

Slices cannot be compared. We cannot use the = = operator to judge whether two slices contain all equal elements. The only valid comparison of slices is with nil. A slice with nil value has no underlying array. The length and capacity of a slice with nil value are 0. But we can't say that a slice with length and capacity of 0 must be nil
Therefore, to judge whether a slice is empty, if len(s) == 0 is used to judge, s == nil should not be used to judge.
That is, nil when no memory address is allocated. If an empty array is allocated, the length and capacity are 0

var s1 []int         //len(s1)=0;cap(s1)=0;s1==nil
s2 := []int{}        //len(s2)=0;cap(s2)=0;s2!=nil
s3 := make([]int, 0) //len(s3)=0;cap(s3)=0;s3!=nil
s1 := make([]int, 5, 10)
s2 := s1
fmt.Println(s1, s2)
s1[0] = 1
fmt.Println(s1, s2)
//[0 0 0 0 0] [0 0 0 0 0]
//[1 0 0 0 0] [1 0 0 0 0]

Use append to add elements

s1 := []string{"beijing", "shanghai", "wuhan"}
fmt.Printf("s1=%v len(s1)=%d cap(s1)=%d\n", s1, len(s1), cap(s1))
// s1[3] = "suzhou" wrong writing, index out of bounds
// After calling the append function, you need to receive the return value with the original slice variable
s1 = append(s1, "suzhou") //append appends the element. If the original underlying array cannot be placed, the GO underlying will replace the underlying array
fmt.Printf("s1=%v len(s1)=%d cap(s1)=%d\n", s1, len(s1), cap(s1))

Note that append needs to pass a value to the original slice
append does not need to create an initial value for the slice before using it

newcap := old.cap
doublecap := newcap + newcap
if cap > doublecap {
	newcap = cap
} else {
	if old.len < 1024 {
		newcap = doublecap
	} else {
		// Check 0 < newcap to detect overflow
		// and prevent an infinite loop.
		for 0 < newcap && newcap < cap {
			newcap += newcap / 4
		}
		// Set newcap to the requested cap when
		// the newcap calculation overflowed.
		if newcap <= 0 {
			newcap = cap
		}
	}
}

From the above code, you can see the following:

  1. First, judge that if the newly applied capacity (cap) is greater than twice the old capacity (old.cap), the final capacity (newcap) is the newly applied capacity (cap).
  2. Otherwise, if the length of the old slice is less than 1024, the final capacity (newcap) is twice the old capacity (old.cap), that is (newcap=doublecap),
  3. Otherwise, if the old slice length is greater than or equal to 1024, the final capacity (newcap) starts from the old capacity (old.cap) and circularly increases by 1 / 4, that is (newcap=old.cap,for {newcap += newcap/4}) until the final capacity (newcap) is greater than or equal to the newly applied capacity (CAP), that is (newcap > = cap)
  4. If the calculated value of the final capacity (cap) overflows, the final capacity (cap) is the newly requested capacity (cap)

It should be noted that slice expansion will be handled differently according to the types of elements in the slice. For example, int and string types are handled differently.

s1 := []string{"beijing", "shanghai", "wuhan"}
fmt.Printf("s1=%v len(s1)=%d cap(s1)=%d\n", s1, len(s1), cap(s1))
// s1[3] = "suzhou" wrong writing, index out of bounds
// After calling the append function, you need to receive the return value with the original slice variable
s1 = append(s1, "suzhou") //append appends the element. If the original underlying array cannot be placed, the GO underlying will replace the underlying array
fmt.Printf("s1=%v len(s1)=%d cap(s1)=%d\n", s1, len(s1), cap(s1))
s2 := make([]string, 3)
s2[0] = "nanjing"
s1 = append(s1, s2...)
fmt.Printf("s1=%v len(s1)=%d cap(s1)=%d\n", s1, len(s1), cap(s1))

When using another slice to append, you need to use that slice To take it apart

s1 := []string{"1", "2", "3"}
s2 := s1
s3 := make([]string, 3, 3)
copy(s3, s2)
s1[1] = "7"
fmt.Println(s1, s2, s3)
//[1 7 3] [1 7 3] [1 2 3]

When using copy, it should be noted that the front is the destination slice position, and the destination position should ensure that the length can accommodate the size of the original slice

s1 := []string{"1", "2", "3"}
// Delete the element with index 1 in s1
s1 = append(s1[:1], s1[2:]...)
fmt.Println(s1)

Note that the slice here also modifies the underlying array through append

s := [...]int{1, 2, 3}
s1 := s[:]
// Delete the element with index 1 in s1
s1 = append(s1[:1], s1[2:]...)
fmt.Println(s1)
fmt.Println(s)
// [1 3]
// [1 3 3]

Two jobs:
1.make will give the element

func main() {
	var a = make([]int, 5, 10)
	for i := 0; i < 10; i++ {
		a = append(a, i)
	}
	fmt.Println(a)
}
//[0 0 0 0 0 0 1 2 3 4 5 6 7 8 9]

2. Sort slices using sort

func main() {
	var a = [...]int{11, 2, 13, 4}
	sort.Ints(a[:])
	fmt.Printf("%v\n", a)
}
//[2 4 11 13]

Topics: Go