Day4 理解 golang slice 用法及原理 IV

这篇主要写两个主题,作为 理解 golang slice 用法及原理 系列的结尾 :

  • nil slice 和 empty slice
  • slice 的常用操作,内容主要来自 SliceTricks - go wiki,几乎所有想得到的 slice 操作都在其中。

nil slice 和 zero length slice

var arr1 []int   // nil slice
arr2 := []int{}  // empty slice

nil slice 代表的是什麽都没有, empty slice 代表长度为 0 的 slice。

再拿宝特瓶的例子出来比喻,empty slice 代表你有一个不能装水的宝特瓶,nil slice 代表你连宝特瓶都没有。
在 go 的语法中 len(arr1)len(arr2) 都为 0,这设计很直觉,因为两者都没水啊。

在大部分情况,这两瓶不能喝水的宝特瓶,意义都是一样的。 这代表着在大部分情况下不需要特别去判断 slice 是 nil 还是 empty。通常只使用 len(arr1) == 0 判断,就去创建一个 slice,或是做其他事情。

但是但是,就是会有例外。你拿着不能装水的宝特瓶去了回收厂可以换钱,但是你双手空空去回收场是换不到钱的,对你来说两者都不能装水,意义是一样的,但是对回收厂来说完全是不同的意义。
看一个实际案例,如果使用 empty slice 和 nil slice 去 marshall 的结果是不一样的,请看程序码。

arr1 := []int{}
arr1M, _ := json.Marshal(arr1)
fmt.Println(string(arr1M))  // print []

var arr2 []int
arr2M, _ := json.Marshal(arr2)
fmt.Println(string(arr2M))  // print null

slice 的各种操作

将 a slice 复制一份到 b

b := make([]T, len(a))

删除第 i 个元素,注意: 这不适用於指标型态或是含有指标型态的 struct。这将会造成 a 的最後一个元素无法被 gc 回收 (memory leak)

a = append(a[:i], a[i+1:]...)

删除第 i 个元素,适用於指标型态或是含有指标型态的 struct

copy(a[i:], a[i+1:])
a[len(a)-1] = nil // or the zero value of T
a = a[:len(a)-1]

删除第 i 到 j - 1 个元素,注意: 这不适用於指标型态或是含有指标型态的 struct。这可能会造成 a 的最後 j - i 个元素无法被 gc 回收 (memory leak)

a = append(a[:i], a[j:]...)

删除第 i 到 j - 1 个元素,适用於指标型态或是含有指标型态的 struct。

copy(a[i:], a[j:])
for k, n := len(a)-j+i, len(a); k < n; k++ {
	a[k] = nil // or the zero value of T
}
a = a[:len(a)-j+i]

插入一个元素在第 i 和 i + 1 个元素中间

s = append(s, 0 /* use the zero value of the element type */)
copy(s[i+1:], s[i:])
s[i] = x

Reference


<<:  烟囱式架构 (Information Silo Architecture)

>>:  【Day 4】VSCode操作Github提取和推送

D29 - 「来互相伤害啊!」:天时地利

互殴之前当然要先有场地才行,让我们建立 Phaser 场景吧! 建立场景 首先建立 src\comp...

DAY 8 - 瓦斯弹

今天继续来练习阴影~ 因为要方便练习~ 所以选一个简单的圆形怪物 我就选了瓦斯弹~ 用他来练习阴影 ...

[Day 27 - 小试身手] Todolist with React (2)

在上一章Todolist with React (1),建立了专案环境、并且拆离 UI 设定好所有...

Laravel 实战经验分享 - Day26 Dockerize 你的 Laravel 专案(下)

昨天在文章中提到如何 Dockerize 你的专案,而设定你自己的 Docker Image 就是一...

Unity自主学习(八):Unity Hub授权Unity引擎

昨天我们都安装好Unity引擎,架设好可以编译程序的环境之後 打开"Unity Hub&q...