当前位置:网站首页>Go language slice

Go language slice

2022-06-11 15:45:00 Crying while learning

Preface

section Slice, It's like an array . Also called variable length array or dynamic array . characteristic : Lengthening .

Slice Is a container of reference type , Points to an underlying array .

establish slice grammar

Normal operation

var slice_name []type
slice_name := []type{v1, v2, v3, v4}

Create slices on an existing array

// Slice name  :=  Array [ Start subscript ,  End subscript ]  Be careful : Does not include end subscript 
slice_name := array_name[start:end]
func main() {
	arr := [9]int{1, 2, 3, 4, 5, 6, 7, 8, 9}
	slice_test1 := arr[1:4] //2-4
	slice_test2 := arr[:5]  //1-5
	slice_test3 := arr[5:]  //6-9
	slice_test4 := arr[:]   //1-9
	fmt.Println(slice_test1)
	fmt.Println(slice_test2)
	fmt.Println(slice_test3)
	fmt.Println(slice_test4)
}

make Keyword creation slice

make Keyword is specifically used to create data of reference type .

grammar

make(type, size1, size2)

The first parameter is the type slice、map、chan

The second parameter is length

The third parameter is capacity .

When the storage length exceeds the capacity , It will automatically expand .

Default storage data ,int Use 0 fill ;string Type with an empty string . Existing values can be defaulted by subscript operation .

func main() {
	slice_test1 := make([]int, 3, 5)
	fmt.Printf("slice_test1: %v; slice length : %v; slice Capacity : %v\n", slice_test1, len(slice_test1), cap(slice_test1))

	//append Elements , exceed slice Capacity 
	slice_test1 = append(slice_test1, 1, 2, 3)
	fmt.Println("---append after ---")
	fmt.Printf("slice_test1: %v; slice length : %v; slice Capacity : %v\n", slice_test1, len(slice_test1), cap(slice_test1))
}

 

slice The effect of assignment on the underlying array

  1. Yes array Element operation , All points to array Of slice The elements of will also change .
  2. Yes slice When the element in , The actual time is right array To operate on the elements of .
  3. slice In case of capacity expansion , It actually opens up a new memory space , So the original array No change .

Concrete example  

1. When the underlying array changes , All points to this array Of slice The value at the response index location also changes .

func main() {
	arr := [6]int{1, 2, 3, 4, 5, 6}
	slice_test1 := arr[:]
	slice_test2 := arr[:3]
	slice_test3 := arr[3:]
	fmt.Println("slice_test1:", slice_test1)
	fmt.Println("slice_test2:", slice_test2)
	fmt.Println("slice_test3:", slice_test3)

	arr[1] += 1
	arr[4] += 1
	fmt.Println("--- Yes array After element operation ---")
	fmt.Println("slice_test1:", slice_test1)
	fmt.Println("slice_test2:", slice_test2)
	fmt.Println("slice_test3:", slice_test3)
}

 

 

2. When operating slice Content time , For instance from slice[index] Modify the value at the index position or use append When adding a value , All of them operate on the underlying array . So the same as (1), Others point to this array Of slice The corresponding position will also change .

func main() {
	arr := [6]int{1, 2, 3, 4, 5, 6}
	slice_test1 := arr[:]
	slice_test2 := arr[:3]
	slice_test3 := arr[3:]
	fmt.Println("slice_test1:", slice_test1)
	fmt.Println("slice_test2:", slice_test2)
	fmt.Println("slice_test3:", slice_test3)

	slice_test1[1] += 1
	slice_test1[4] += 1
	fmt.Println("--- Yes slice After element operation ---")
	fmt.Println("slice_test1:", slice_test1)
	fmt.Println("slice_test2:", slice_test2)
	fmt.Println("slice_test3:", slice_test3)
}

 

3. When using append to slice Added value , operation slice Capacity ,slice In capacity .slice Add capacity , Will open up a new memory address . The original array Copy the values in ; Add new values after capacity expansion . Therefore, the newly added value in the case of capacity expansion will not affect the original value array To operate .

therefore slice In case of capacity expansion , Only those that have been expanded slice The value in the .array It won't change , Other points to the original array Of slice The value in does not change .

func main() {
	arr := [6]int{1, 2, 3, 4, 5, 6}
	slice_test1 := arr[:]
	slice_test2 := arr[:3]
	slice_test3 := arr[3:]
	fmt.Printf("slice_test1: %v; slice_test1 length : %v; slice_test1 Capacity : %v \n", slice_test1, len(slice_test1), cap(slice_test1))
	fmt.Println("slice_test2:", slice_test2)
	fmt.Println("slice_test3:", slice_test3)

	slice_test1 = append(slice_test1, 7, 8, 9)
	slice_test1[1] += 1
	slice_test1[4] += 1

	fmt.Println("---slice_test1 In case of capacity expansion ---")
	fmt.Println(" Original array arr:", arr)
	fmt.Println("slice_test1:", slice_test1)
	fmt.Println("slice_test2:", slice_test2)
	fmt.Println("slice_test3:", slice_test3)
}

 

append Insert elements

grammar

slice_name = append(slice_name, v1, v2)
slice_name = append(slice_name, slicename2...)

  You can put slice_name2 The values of the slice are all inserted slice_name in . however slice_name2 There must be three points behind it , Representation time slice .

func main() {
	slice_test1 := []int{1, 2, 3}
	slice_test2 := []int{4, 5, 6}
	fmt.Println("append front slice_test1:", slice_test1)

	slice_test1 = append(slice_test1, slice_test2...)
	fmt.Println("appendslice_test2 after slice_test1:", slice_test1)

	slice_test1 = append(slice_test1, 7, 8, 9)
	fmt.Println("append After a single element slice_test1:", slice_test1)
}

 

section Slice Memory analysis

  When checking the memory address . value type , Such as array、int etc. ,fmt.Printf(%p\n, &arr) , You want to add... Before the variable & Symbol ; Reference type , Such as slice,fmt.Printf(%p\n, slice1) , No need to add & Symbol .

func main() {
	s1 := []int{1, 2, 3, 4}
	fmt.Println(s1)
	fmt.Printf("s1 The address of : %p; s1 The length of : %v; s1 The capacity of : %v \n", s1, len(s1), cap(s1))

	s1 = append(s1, 5, 6)
	fmt.Println(s1)
	fmt.Printf("s1 The address of : %p; s1 The length of : %v; s1 The capacity of : %v \n", s1, len(s1), cap(s1))
}

1. Create array s1 when , First, create an underlying array . Then slice s1 Point to the underlying array . At this time, the length and capacity are the same .

2. Slices themselves do not store data , Are the underlying array storage data . So modifying is also modifying the underlying array .

3. Capacity expansion : When the underlying array is expanded , Its capacity is doubled . So use append Operation slice , In case of capacity expansion ,slice The capacity of is also multiplied .

4. Because the expansion needs to change the underlying array , So the memory address of the underlying array has changed ; If you don't need to expand , The memory address will not change . 

 

原网站

版权声明
本文为[Crying while learning]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/162/202206111536126566.html