golang切片操作


一、切片:

Go 语言切片Slice是对数组的抽象,是引用类型。

Go 数组的长度不可改变,在特定场景中这样的集合就不太适用,Go 中提供了一种灵活,功能强悍的内置类型切片("动态数组")。

与数组相比,切片的长度是不固定的,可以追加元素,在追加时可能使切片的容量增大。

 

[5]int 是数组,而 []int 是切片。

切片的数据结构中,包含一个指向数组的指针 array ,当前长度 len ,以及最大容量 cap
在使用 make([]int, len) 创建切片时,实际上还有第三个可选参数 cap ,也即 make([]int, len, cap)
在不声明 cap 的情况下,默认 cap=len
当切片长度没有超过容量时,对切片新增数据,不会改变 array 指针的值。

二、切片扩容

  • 当原切片长度小于1024时,新切片的容量会直接翻倍。
  • 而当原切片的容量大于等于1024时,会反复地增加25%,直到新容量超过所需要的容量。
  • 当需要的容量超过原切片容量的两倍时,会使用需要的容量作为新容量。

三、定义切片

1.声明var定义一个nil的切片。

  var tmp []int

2.使用make定义一个指定长度的切片

  var tmp []int = make([]int ,10)

3.使用推导式

  tmp := make([]int, 10)

4.也可以指定容量,其中 capacity 为可选参数。

  tmp make([]T, length, capacity)

注意:nil切片和空切片的区别

nil切片:

// 创建 nil 整型切片
var myNum []int

空切片:

// 使用 make 创建空的整型切片
myNum := make([]int, 0)
// 使用切片字面量创建空的整型切片
myNum := []int{}

 无论是nil切片,还是空切片,都可以使用append, copy等方法。

无论是nil切片,还是空切片,都可以使用len(),他们的长度都是0。

要注意的是nil切片 == nil,但是 空切片 != nil。

四、切片初始化

s :=[] int {1,2,3 }

 s := arr[:]

五、切片操作

1.append

s1 := []int{1, 2, 3, 4, 5} //短操作符声明 len为4,cap为4
s2 := make([]int, 2, 4)    //make语法声明 ,len为2,cap为4

s3 := append(s2, 7) //append一个元素

s4 := append(s2, s1...) //append  一个切片所有的元素

 2.copy

copy(s1, s2)    //  复制,用s2的元素填充s1里去,改变原slice,覆盖对应的key

 3.删除一个元素

//删除第三个元素
s7 := append(s1[:1], s1[3:]...)

 4.修改

 // 修改原始数据的第一个元素
s7[0] = 999

 5.遍历

    // 切片遍历
    var arr [5]int = [...]int{10,20,30,40,50}
    slice := arr[1:4]

    // for循环方式
    for i := 0; i < len(slice); i++ {
        fmt.Printf("slice[%v]=%v", i, slice[i])
    }
    fmt.Println()

    // for range方式
    for index, value := range slice {
        fmt.Printf("i=%v v=%v\n", index, value)
    }

 6.

sli := slice[:] // 引用一个切片
slice = slice[:0] // 清空一个切片

 

 六、切片的几个坑

由于切片是引用类型,不是值类型。类似于py的列表,也是引用类型。

第一个坑:子切片和父切片用的是同一个底层数组

pSlice := []int{0, 10, 20, 30, 40}
//新建一个子切片,指定元素为pSlice的index 1到3(不包括3),即{10, 20}
subSlice := pSlice[1:3] 

//这时候,改变subSlice的值,也会改动到pSlice
subSlice[1] = 22
fmt.Println(pSlice)    //{0, 10, 22, 30, 40}
fmt.Println(subSlice)    //{10, 22}

 

append,同样会产生这样的问题。

//append操作会返回一个新切片,同样共享底层数组
subSlice = append(subSlice, 33) 
这时候两个slice的值如下:
pSlice    //{0, 10, 22, 33, 40}
subSlice   //{10, 22, 33}

第二个坑:for range遍历的是副本

 

 

 

 

 

 

 

 

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM