美文网首页
今天,我们来聊一聊 Golang 中的 Slice(切片)

今天,我们来聊一聊 Golang 中的 Slice(切片)

作者: 齐舞647 | 来源:发表于2020-06-10 22:14 被阅读0次

前言:
因为工作需要,最近接触 Golang 比较多。
也希望自己的技术栈能从一个 iOS 转变成 iOS / Golang。


那么,今天我们来聊一聊Golang中的数组(Array)和切片(Slice)。

一、Array(数组)

数组我们肯定都是熟悉的,
在Go语言中数组(Array)在初始化后,长度是固定的。

与其他语言类似,在这里举一些在Go中数组的简单demo。

var arr [10]int // 声明,len与cap为10,值默认补0。
arr := []int {1,2,3,4} // 快速声明,len与cap为4,值为[1,2,3,4]。
arr := [5]int {1,2,3,4} // 快速声明,len与cap为5,值为[1,2,3,4,0],末尾默认补0。

// 数组的遍历
for i := 0; i < len(arr); i++ {
    fmt.Println(arr[i])
}

二、Slice(切片)

接下来是今天的主角:Slice。

首先,切片是一种引用类型。(与字典map、通道channel一样,都是引用类型)
有点类似于我们iOS中的MutableArray
暂时可理解为一种可变长的“动态数组”。

注意:
因此,我们取数组的切片时,如果不希望切片的修改会对原有数组产生影响的话,需要对Slice进行Copy操作。

基本使用

numbers := []int{1,2,3,4,5,6,7,8,9,10}

// 半闭半开结构
slice1 := numbers[:] // 直接对numbers的引用
slice1 = numbers[1:10] // 从numbers[1]到numbers[9]
slice1 = numbers[:5] // 从开始到numbers[4]
slice1 = numbers[7:] // 从numbers[7]开始到末尾

slice1 = append(slice1, 1,2,3,4,5) // 追加长度
fmt.Println(slice1) // 打印:[8 9 10 1 2 3 4 5]

slice2 := make([]int, len(slice1), cap(slice1)*2) // 手动声明一个slice2,最大长度cap为slice1的两倍。
copy(slice2,slice1) //将slice1的数据copy到slice2
slice2 = append(slice2,1,2,3) // 在对slice2进行追加

fmt.Println(slice1)  // 打印:[8 9 10 1 2 3 4 5]
fmt.Println(slice2)  // 打印:[8 9 10 1 2 3 4 5 1 2 3]

fmt.Printf("len = %d, cap = %d", len(slice1), cap(slice1)) // 打印当前长度len,与最大容量cap。

扩容策略

Slice的长度(len)即将超过最大容量(cap)时,Go语言会对Slice进行扩容。

具体策略为:

  • Slice的长度(len)小于1024时,Go语言会对该Slice进行 “2倍”扩容
  • Slice的长度(len)大于等于1024时,Go语言会对该Slice进行 “1.25倍”扩容
len 扩容策略
<1024 2倍扩容
>=1024 1.25倍扩容

感兴趣的同学,可以使用下面的代码,自己试一下它的扩容策略。

slice2 := make([]int,10,10)
fmt.Printf("len = %d, cap = %d\n", len(slice2), cap(slice2)) // 打印当前长度len,与最大容量cap。 // 获取len与cap的长度。
slice2 = append(slice2, 1,2,3,4,5) // 追加数据
fmt.Printf("len = %d, cap = %d\n", len(slice2), cap(slice2)) // 打印当前长度len,与最大容量cap。 // 获取len与cap的长度。

一些注意点(坑)

  1. 切记切记,切片是一种引用类型。如果改切片的值不希望改动原有数据,一定要先copy一份。

  2. 对切片的遍历时,系统会对value进行一次值拷贝。因此不能对value进行引用操作,否则可能会造成panic。如果需要引用操作,请去下标。

相关文章

  • 今天,我们来聊一聊 Golang 中的 Slice(切片)

    前言:因为工作需要,最近接触 Golang 比较多。也希望自己的技术栈能从一个 iOS 转变成 iOS / Gol...

  • 今天我们来聊一聊WebSocket(iOS/Golang)

    前言:前段时间,在公司的项目中用到了WebSocket,当时没有时间好好整理。最近,趁着有时间,就好好梳理了一下W...

  • Golang 中的数组 (array) 和切片 (slice)

    huangwenwei - 字里行间 | Golang 中的数组 (array) 和切片 (slice) 中文描述...

  • Go-Slice

    golang 切片(Slice) 切片为引用类型,切片(Slice)是一个拥有相同类型元素的可变长度的序列。它是基...

  • Learn Golang in 21 Days - Day 10

    Learn Golang in 21 Days - Day 10 知识点 切片Slice Slice是对数组的抽象...

  • slice切片做函数参数

    首先要明确一点:slice作为函数参数是值传递. 再来分析一下golang中的切片slice底层的实现细节...

  • golang:slice切片

    golang中的切片的索引是左闭右开的,切片不存储数据,它是对数组的引用,其他切片可以跟它共享同一个底层的数组,所...

  • Golang——切片slice

    切片是一个拥有相同类型元素的可变长度的序列,底层基于数组类型进行封装。切片是一个引用类型,内部结构包括地址(切片中...

  • 今天,我们来聊一聊自由

    前段时间在知乎上看到一个问题:人终其一生在追求什么? 自由,是其中一个最重要的答案。 我其实不是很喜欢讨论这种宏大...

  • 今天,我们来聊一聊“人设”

    算来,我已经有两天没在简书上日更了。 原因主要是因为我实在是没有写作的思路了,也不知道该写些什么,总觉得没有输入的...

网友评论

      本文标题:今天,我们来聊一聊 Golang 中的 Slice(切片)

      本文链接:https://www.haomeiwen.com/subject/nxqmtktx.html