一、概述

数组(Array)的长度在定义之后无法再次修改;数组是值类型,每次传递都将产生一份副本。

显然这种数据结构无法完全满足开发者的真实需求。Go语言提供了数组切片(slice)来弥补数组的不足。

切片并不是数组或数组指针,它通过内部指针和相关属性引⽤数组⽚段,以实现变⻓⽅案。

slice并不是真正意义上的动态数组,而是一个引用类型。slice总是指向一个底层array,slice的声明也可以像array一样,只是不需要长度。

【Go语言基础】slice-LMLPHP

二、基本语法

切片的创建和初始化

slice和数组的区别:声明数组时,方括号内写明了数组的长度或使用...自动计算长度,而声明slice时,方括号内没有任何字符。

var s1 []int //声明切片和声明array一样,只是少了长度,此为空(nil)切片
s2 := []int{}

//make([]T, length, capacity) //capacity省略,则和length的值相同
var s3 []int = make([]int, 0)
s4 := make([]int, 0, 0)

s5 := []int{1, 2, 3} //创建切片并初始化

注意:make只能创建slice、map和channel,并且返回一个有初始值(非零)。

// runtime/slice.go
type slice struct {
    array unsafe.Pointer // 元素指针
    len   int // 长度 
    cap   int // 容量
}

【引申1】[3]int 和 [4]int 是同一个类型吗?

不是。因为数组的长度是类型的一部分,这是与 slice 不同的一点。

三、切片的操作

切片截取

示例说明:

array := []int

【Go语言基础】slice-LMLPHP

【Go语言基础】slice-LMLPHP

append

append函数向 slice 尾部添加数据,返回新的 slice 对象:

var s1 []int //创建nil切换
//s1 := make([]int, 0)
s1 = append(s1, 1)       //追加1个元素
s1 = append(s1, 2, 3)    //追加2个元素
s1 = append(s1, 4, 5, 6) //追加3个元素
fmt.Println(s1)          //[1 2 3 4 5 6]

s2 := make([]int, 5)
s2 = append(s2, 6)
fmt.Println(s2) //[0 0 0 0 0 6]

s3 := []int{1, 2, 3}
s3 = append(s3, 4, 5)
fmt.Println(s3)//[1 2 3 4 5]

append函数会智能地底层数组的容量增长,一旦超过原底层数组容量,通常以2倍容量重新分配底层数组,并复制原来的数据:

func main() {
    s := make([]int, 0, 1)
    c := cap(s)
    for i := 0; i < 50; i++ {
        s = append(s, i)
        if n := cap(s); n > c {
            fmt.Printf("cap: %d -> %d\n", c, n)
            c = n
        }
    }
    /*
        cap: 1 -> 2
        cap: 2 -> 4
        cap: 4 -> 8
        cap: 8 -> 16
        cap: 16 -> 32
        cap: 32 -> 64
    */
}

slice对底层数组的修改

package main

import "fmt"

func main() {
	slice := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
	s1 := slice[2:5]
	fmt.Println(s1) //[2 3 20]

	s2 := s1[2:6:7] // 4,5,6,7
	s2 = append(s2, 100)
	s2 = append(s2, 200)
	fmt.Println(s2) //[4 5 6 7 100 200]

	s1[2] = 20//0, 1, 2, 3(赋值), 4, 5, 6, 7, 8, 9

	fmt.Println(slice) //[0 1 2 3 20 5 6 7 100 9]

//问题1:100怎么来的。
//问题2:为什么100后面是9不是200
}
02-21 09:07