Go1.22 Slices 的一些变化

简介

在最新的Go 1.22 rc版本中, Slices增加了一些新特性。这些变更涉及Concat、Compact、CompactFunc、Delete、DeleteFunc、Replace、Insert等函数,更方便开发者对切片数据进行处理。本文将简介一下这些变化、优势和使用时需要注意的地方。

1. Concat

go 复制代码
// Concat returns a new slice concatenating the passed in slices.
func Concat[S ~[]E, E any](slices ...S) S

新增的Concat将传入的切片连接起来,返回一个新的切片。在之前版本版本,在拼接切片时我们或是使用迭代或者循环的方式,例如

go 复制代码
package main

import "fmt"

func main() {
    slice1 := []int{1, 2, 3}
    slice2 := []int{4, 5, 6}
    result := Concat(slice1, slice2)
    fmt.Println(result) 
}

func Concat(slices ...[]int) []int {
    var result []int
    for _, slice := range slices {
        result = append(result, slice...)
    }
    return result
}
// 输出 [1 2 3 4 5 6]

rc版本中,新增加了slice.Concat,详细如下:

go 复制代码
import "slices" 
result := slices.Concat(slice1, slice2)
// 输出 [1 2 3 4 5 6]

可见,concat可读性更高且更加简洁。

2 Delete、Compact、Replace 变化

缩小切片大小的函数(Delete、DeleteFunc、Compact、CompactFunc和Replace)现在将新长度和旧长度之间的元素归零。

Delete

go 复制代码
// Delete removes the elements s[i:j] from s, returning the modified slice.
// Delete panics if j > len(s) or s[i:j] is not a valid slice of s.
// Delete is O(len(s)-i), so if many items must be deleted, it is better to
// make a single call deleting them all together than to delete one at a time.
// Delete zeroes the elements s[len(s)-(j-i):len(s)].
func Delete[S ~[]E, E any](s S, i, j int) S
 

Delete 1.22之前的版本:

csharp 复制代码
newSlice11 := slices.Delete(slice1, 2, 3)
fmt.Println(newSlice11)
//输出
[1 2]
[1 2 3]

Delete 1.22rc版本中

csharp 复制代码
newSlice11 := slices.Delete(slice1, 2, 3)
fmt.Println(newSlice11)
//输出 
[1 2]        
[1 2 0] 

Compact

go 复制代码
// Compact将连续运行的相等元素替换为单个副本。
//这类似于Unix上的uniq命令。
// Compact修改片s的内容并返回修改后的片;
//可以有更小的长度。
// Compact将新长度和原长度之间的元素归零。
func Compact[S ~[]E, E comparable](s S) S 

Compact 1.22之前的版本:

go 复制代码
slice3 := []int{1, 1, 2, 3, 4, 6}
seq := slices.Compact(slice3)
fmt.Println(seq)
fmt.Println(slice3) 
//输出
[1 2 3 4 6]
[1 2 3 4 6 6]

Compact 1.22 rc版本中

go 复制代码
//输出
[1 2 3 4 6]  
[1 2 3 4 6 0]

Replace

go 复制代码
// Replace将元素s[i:j]替换为给定的v,并返回
//修改切片。
//如果j > len(s)或s[i:j]不是s的有效切片,则替换panic。
//当len(v) < (j-i)时,将新长度与原长度之间的元素替换为零。
func Replace[S ~[]E, E any](s S, i, j int, v ...E) S 
go 复制代码
slice2 := []int{4, 5, 6}
newSlice2 := slices.Replace(slice2, 0, 2, 99)
fmt.Println(newSlice2) //
fmt.Println(slice2)    //

之前的版本:

csharp 复制代码
[99 6]
[99 6 6]

1.22 rc版本中

csharp 复制代码
[99 6]  
[99 6 0]

3.Insert 可能 panic

Insert现在,如果参数i超出范围,总是会出现panic 。以前,如果没有要插入的元素,它不会在这种情况下出现恐慌。

在下面的例子中,往slice的x位置插入一个元素,但是没有具体的值。

之前的版本

go 复制代码
slice2 := []int{4, 5, 6}
newSlice2 := slices.Insert(slice2, 4)
fmt.Println(newSlice2) 
// 输出 [4 5 6]

1.22 版本

go 复制代码
panic: runtime error: slice bounds out of range [4:3]

可见,之前版本可以正常执行,1.22会抛出异常。

总结

Go 1.22中,Slice有一些新特性的变化,包括:新增函数Concat用于连接多个切片。缩小切片大小的函数(Delete、DeleteFunc、Compact、CompactFunc和Replace)现在将新长度和旧长度之间的元素归零。Insert现在,如果参数i超出范围,总是会出现恐慌。以前,如果没有要插入的元素,它不会在这种情况下出现恐慌。虽然不是大的特性变化,但确实方便了开发者对slice数据的一些操作,提高了代码的可读性和开发效率,减少了冗余的逻辑,更加简洁。

参考

相关推荐
喵个咪2 小时前
GoWind 拆解:全链 ID 类型体系——int64 定版与前端字符串化契约
前端·后端·go
喵个咪2 小时前
GoWind CMS 拆解:发布审批——多级推进、逐级角色与全程留痕
前端·后端·go
喵个咪2 小时前
GoWind Flow 拆解:一个 Go 工作流引擎与它的双模式设计器
前端·后端·go
喵个咪3 小时前
GoWind CMS 拆解:搜索三板斧——高亮、联想、同义词
后端·搜索引擎·go
喵个咪3 小时前
GoWind 拆解:AI Agent 编排引擎——波次并行、子图递归与人工审批
人工智能·后端·go
喵个咪3 小时前
GoWind Admin 拆解:打印模板设计器——从画布到服务端 PDF 的完整打印链路
前端·后端·go
喵个咪4 小时前
GoWind Admin 拆解:BI 大屏设计器——schema 即 JSON、resolver 注入与三张快照表的口径谱系
大数据·后端·go
Warson_L18 小时前
高性能架构设计
python·go
我不会起名字32219 小时前
Redis 从 0 到 1(三十七·收官):36 篇浓缩成 1 张知识地图 + 50 项生产 Checklist
redis·go·知识体系·checklist·收官
Mz码不住19 小时前
用 Wails 写一个跨平台进程管理器
go