作者:陈明勇
个人网站:https://chenmingyong.cn
文章持续更新,如果本文能让您有所收获,欢迎点赞收藏加关注本号。 微信阅读可搜《程序员陈明勇》。 这篇文章已被收录于 GitHub https://github.com/chenmingyong0423/blog,欢迎大家 Star 催更并持续关注。
扫码关注公众号,手机阅读更方便
前言
Go 1.22 版本于 2024 年 2 月 6 日发布,引入了几个重要的特性和改进。在标准库层面上,该版本对 slices 库进行了更新,更新内容包括以下三个方面:
- 新增
Concat函数:该函数能够高效地拼接多个切片。 - 零化处理:
Delete、DeleteFunc、Compact、CompactFunc和Replace函数在原切片中将 被移除的元素 置为零值(被移除的元素 是指从原切片中移除的指定元素,在新切片中不存在)。 - 越界插入优化:在使用
Insert函数时,若参数i超出切片的范围,则总会触发panic。而在Go 1.22版本之前,即使i越界了,在没有指定插入元素的情况下,该行为不会触发panic。
本文将详细介绍 Go 语言 slices 库在 Go 1.22 版本中的更新内容。
准备好了吗?准备一杯你最喜欢的咖啡或茶,随着本文一探究竟吧。

新增函数 Concat:高效拼接切片
Concat 函数接受一个不定参数 slices,参数类型为切片,该函数用于将多个切片拼接到一个新的切片里并返回新切片。
代码示例:
package main
import (
"fmt"
"slices"
)
func main() {
s1 := []string{
"Go slices", "Go maps"}
s2 := []string{
"Go strings", "Go strconv"}
s3 := []string{
"程序员", "陈明勇"}
s4 := slices.Concat(s1, s2, s3)
fmt.Printf("cap: %d, len: %d\n", cap(s4), len(s4))
fmt.Println(s4)
}
代码运行结果如下所示:
cap: 6, len: 6
[Go slices Go maps Go strings Go strconv 程序员 陈明勇]
根据运行结果可知,Concat 函数将所给定的切片集的元素都拼接到一个新切片里,并且新切片的容量和长度是所给定切片集长度的总和。
我们来看看 Concat 函数的源码实现:
// Concat returns a new slice concatenating the passed in slices.
func Concat[S ~[]E, E any](slices ...S) S {
size := 0
for _, s := range slices {
size += len(s)
if size < 0 {
panic("len out of range")
}
}
newslice := Grow[S](nil, size)
for _, s := range slices {
newslice = append(newslice, s...)
}
return newslice
}
Concat 函数的源码实现非常简洁,它在拼接切片之前先计算了新切片所需的长度,然后利用 Grow 函数初始化新切片。这样做的好处是避免了后续 append 操作中因为切片扩容而导致的内存重新分配和复制问题,使得函数更加高效。
这里留一个悬念:你们知道在什么情况下, if size < 0 这个看似不会成立的分支会成立吗?_ 欢迎在评论区发表你的见解。
零化处理
在 Go 1.22 版本中,对 Delete、DeleteFunc、Compact、CompactFunc 和 Replace 函数进行了更新。这些函数的共同点是接受一个给定的切片参数,记为 s1,并返回一个新切片,记为 s2。被移除的元素会在 s1 中被置为零值(被移除的元素 是指从 s1 中移除的指定元素,在s2 中不存在)。
Delete 函数
通过不同 Go 版本的代码示例来感受 Delete 函数 零化处理 的更新。
-
Go 1.21版本的代码示例package main import ( "fmt" "slices" ) func main() { s1 := []

本文详细解读了Go1.22版本中slices库的新功能,包括Concat函数的高效拼接、Delete等函数的零化处理以及Insert函数的越界插入优化。
最低0.47元/天 解锁文章
1391

被折叠的 条评论
为什么被折叠?



