func main() { s1 := []string{"煎鱼", "咸鱼", "摸鱼"} s2 := []string{"炸鱼", "水鱼", "煎鱼"} s3 := append(s1, s2...) fmt.Println(s3) }输出结果:
[煎鱼 咸鱼 摸鱼 炸鱼 水鱼 煎鱼]
func concatSlice[T any](first []T, second []T) []T { n := len(first) return append(first[:n:n], second...) } func main() { s1 := []string{"煎鱼", "炸鱼"} s2 := []string{"水鱼", "摸鱼", "煎鱼"} s3 := concatSlice(s1, s2) fmt.Println(s3) }输出结果:
[煎鱼 炸鱼 水鱼 摸鱼 煎鱼]
func Concat[S ~[]E, E any](slices ...S) S使用案例如下:
import ( "fmt" "slices" ) func main() { s1 := []string{"煎鱼"} s2 := []string{"炸鱼", "青鱼", "咸鱼"} s3 := []string{"福寿鱼", "煎鱼"} resp := slices.Concat(s1, s2, s3) fmt.Println(resp) }该函数是基于泛型实现的,不需要像以前一样,每个类型都在内部实现一遍。用户使用起来非常方便。但需要确保传入的切片类型都是一致的。
// 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 }需要注意的是:当 size < 0 时会触发 panic。但我感觉这更多只是一个防御性的编程处理。一般情况下不会被触发。
func main() { s1 := []int{11, 12, 13, 14} s2 := slices.Delete(s1, 1, 3) fmt.Println("s1:", s1) fmt.Println("s2:", s2) }输出结果:
s1: [11 14 13 14] s2: [11 14]新版本程序不变,运行结果发生了改变,输出结果为:
s1: [11 14 0 0] s2: [11 14]Compact 函数
func main() { s1 := []int{11, 12, 12, 12, 15} s2 := slices.Compact(s1) fmt.Println("s1:", s1) fmt.Println("s2:", s2) }输出结果:
s1: [11 12 15 12 15] s2: [11 12 15]新版本程序不变,运行结果发生了改变,输出结果为:
s1: [11 12 15 0 0] s2: [11 12 15]Replace 函数
func main() { s1 := []int{11, 12, 13, 14} s2 := slices.Replace(s1, 1, 3, 99) fmt.Println("s1:", s1) fmt.Println("s2:", s2) }输出结果:
s1: [11 99 14 14] s2: [11 99 14]新版本程序不变,运行结果发生了改变,输出结果为:
s1: [11 99 14 0] s2: [11 99 14]变更 Insert 函数行为,可能会 panic
func main() { s1 := []string{"煎鱼", "炸鱼", "水鱼"} s2 := slices.Insert(s1, 4) fmt.Println("s1:", s1) fmt.Println("s2:", s2) }输出结果:
# 堆代码 duidaima.com panic: runtime error: slice bounds out of range [4:3] goroutine 1 [running]: slices.Insert[...]({0xc00010e0c0?, 0x10100000010?, 0x7ecd5be280a8?}, 0xc00010aee8?, {0x0?, 0x60?, 0x10052e4c0?}) ...以上场景是使用 slices.Insert 函数下,以前没有填入具体要插入的元素,是会正常运行的。在新版本起,会直接导致 panic。当然,如果一开始就有填入。无论是新老版本,都会导致 panic。相当于是修复了一个边界值了。