go中的数组和切片

声明:

package main

import "fmt"

func main() {
	// 数组声明
	s1 := make([]int,5)
	fmt.Printf("The length of s1: %d\n", len(s1))   //5
	fmt.Printf("The capacity of s1: %d\n", cap(s1))   //5
	fmt.Printf("The value of s1: %d\n", s1)    // [0 0 0 0 0]

	s4 := [5]int{0,1,2}
	fmt.Printf("The length of s4: %d\n", len(s4))   //5
	fmt.Printf("The capacity of s4: %d\n", cap(s4))   //5
	fmt.Printf("The value of s4: %d\n", s4)   // [0 1 2 0 0]

	// 切片声明
	s2 := make([]int, 5, 8)
	fmt.Printf("The length of s2: %d\n", len(s2))   //5
	fmt.Printf("The capacity of s2: %d\n", cap(s2))   //8
	fmt.Printf("The value of s2: %d\n", s2)   // [0 0 0 0 0]

	s3 := []int{0,1,2,3,4}
	fmt.Printf("The length of s3: %d\n", len(s3))   //5
	fmt.Printf("The capacity of s3: %d\n", cap(s3))   //5
	fmt.Printf("The value of s3: %d\n", s3)   // [0 1 2 3 4]


}

数组的长度是不可变的,而切片的长度是可变的,他的底层数据结构是一个数组。数组可以被叫做切片的底层数组,而切片也可以被看做是对数组的某个连续片段的引用。

数组的容量永远等于其长度,都是不可变的。切片的容量却不是这样,一旦一个切片无法容纳更多的元素,go语言就会想办法扩容。但它并不会改变原来不的切片,而时会生成一个容量更大的切片,然后将原有的元素和新元素一并拷贝到新切片中。在一般情况下,新切片容量将会是旧切片容量的2倍,但是当原切片的长度大于等于1024时,go语言将会以原容量的1.25倍作为新容量的基准。

虽然在扩容的时候go语言一定会生成新的底层数组,但是它也同事生成了新的切片。它只是把新的切片作为了新底层的窗口,而没有对原切片及其底层数组做任何改动。

package main

import "fmt"

func main() {
	//数组的扩容是2倍增加
	s1:=[]int{0,1,2,3}
	fmt.Printf("The length of s1: %d\n", len(s1))   //4
	fmt.Printf("The capacity of s1: %d\n", cap(s1))   //4
	fmt.Printf("The value of s1: %d\n", s1)   // [0 1 2 3]
	s1=append(s1, 4)
	fmt.Printf("The length of s1: %d\n", len(s1))   //5
	fmt.Printf("The capacity of s1: %d\n", cap(s1))   //8
	fmt.Printf("The value of s1: %d\n", s1)   //  [0 1 2 3 4]

	//浅拷贝
	s2:=s1[0:len(s1)]
	s2[0]=11
	fmt.Printf("The value of s2[0]: %d\n", s2[0])  //11
	fmt.Printf("The value of s1[0]: %d\n", s1[0])  //11

	//深拷贝
	// copy 函数提供深拷贝功能
	// 但需要在拷贝前申请空间
	s3 := make([]int, 5, 5)
	copy(s3, s1)
	s3[0]=111
	fmt.Printf("The value of s3[0]: %d\n", s3[0])  //111
	fmt.Printf("The value of s1[0]: %d\n", s1[0])  //11
	
}

切片的缩容:

package main

import "fmt"

func main() {
	s1:=[]int{0,1,2,3,4,5,6,7,8}
	fmt.Printf("The length of s1: %d\n", len(s1))   //9
	fmt.Printf("The capacity of s1: %d\n", cap(s1))   //9
	fmt.Printf("The value of s1: %d\n", s1)   // [0 1 2 3 4 5 6 7 8]

	//删除切片元素remove element at index
	index:=5;
	s1=append(s1[:index-3],s1[index+3:]...)
	fmt.Printf("The length of s1: %d\n", len(s1))   //3
	fmt.Printf("The capacity of s1: %d\n", cap(s1))   //9
	fmt.Printf("The value of s1: %d\n", s1)   // [0 1 8]

	//可以看到切片缩容之后还是会引用底层的原数组,
	// 这有时候会造成大量缩容之后的多余内容没有被垃圾回收。
	// 可以使用新建一个数组然后copy的方式。
	s2:=make([]int,3,3)
	copy(s2,s1)

	fmt.Printf("The length of s2: %d\n", len(s2))   //3
	fmt.Printf("The capacity of s2: %d\n", cap(s2))   //3
	fmt.Printf("The value of s2: %d\n", s2)   // [0 1 8]
}

猜你喜欢

转载自blog.csdn.net/qq_20867981/article/details/86467539