对比以下两种操作方式:
第一种
package main
import "fmt"
func main() {
t := []int{1, 2, 4, 5}
a := t[:2]
b := t[2:]
fmt.Println(t)
fmt.Println(a)
fmt.Println(b)
a = append(a, 3)
fmt.Println(t)
fmt.Println(a)
fmt.Println(b)
}
输出结果:
[1 2 4 5]
[1 2]
[4 5]
[1 2 3 5]
[1 2 3]
[3 5]
第二种
package main
import "fmt"
func main() {
t := []int{1, 2, 4, 5}
a := t[:2:2] // 细微处改变
b := t[2:]
fmt.Println(t)
fmt.Println(a)
fmt.Println(b)
a = append(a, 3)
a = append(a, b...)
fmt.Println(t)
fmt.Println(a)
fmt.Println(b)
}
输出结果:
[1 2 4 5]
[1 2]
[4 5]
[1 2 4 5]
[1 2 3]
[4 5]
第二种与第一种的细微处改变唯一的区别就是从 t
裁剪出 a
的时候,指定了cap
:
a := t[:2:2]
第一种未指定的情况下,a
初始化cap
和t
是一致的,但是对于b
初始化出来的cap
和len
一致,都是2
。但是这里如果指定的cap
和t
保持一致,依旧会有问题,结果不符合预期。
想请教一下各位导致这种情况的原因是什么,是否能找到相关的官方文档看一下。
这个问题具体来源于我希望在slice指定位置插入一个元素:
package main
import "fmt"
func main() {
t := []int{1, 2, 4, 5}
r := append(append(t[:2], 3), t[2:]...)
fmt.Println(r) // 结果:[1 2 3 3 5],不符合预期
}
首先 对于 s[start:end] 这样的操作,在操作完成之后,还是指向原来的 slice,这点在官方文档中有体现:https://go.dev/ref/spec#Slice...
其实,最关键的一个理解是,slice[1:3] 这样类似的切分操作,不要理解为是将原来的slice 进行取出,重新赋值;而理解成一个视图,只是看到了一部分。
最后,如何在 slice 插入一个元素,可以尝试这样解决