企业🤖AI Agent构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
# **切片基本操作** 使用下面的代码可创建一个切片字面量: ```go aSliceLiteral := []int{1, 2, 3, 4, 5} ``` 与定义数组相比,**切片字面量**只是没有指定元素数量。如果你在[]中填入数字,你将得到的是数组。 也可以使用*make()*创建一个空切片,并指定切片的长度和容量。容量这个参数可以省略,在这种情况下容量等于长度。 下面定义一个长度和容量均为20的空切片,并且在其需要的时候会自动扩容: ```go integer := make([]int, 20) ``` Go自动将空切片的元素初始化为对应元素的初始值,意味着切片初始化时的值是由切片类型决定的。 使用下面的代码遍历切片中的元素: ```go for i :=0; i < len(integer); i++ { fmt.Println(i) } ``` 切片变量的零值是nil, 下面代码可将已有的切片置为空: ```go aSliceLiteral = nil ``` 可以使用**append()**函数追加元素到切片,此操作将触发切片自动扩容。 ```go integer = append(integer, 12345) ``` `integer[0]`代表切片integer的第一个元素,`integer[len(integer)-1]`代表最后一个元素。 同时,使用`[:]`操作可以获取连续多个元素,下面的代码表示获取第2、3个元素: ```go integer[1:3] ``` `[:]`操作也可以帮助你从现有的切片或数组中创建新的切片或数组: ```go s2 := integer[1:3] ``` 这种操作叫做re-slicing,在某种情况下可能会导致bug: ```go package main import "fmt" func main() { ​ s1 := make([]int, 5) ​ reSlice := s1[1:3] ​ fmt.Println(s1) ​ fmt.Println(reSlice) ​ reSlice[0] = -100 ​ reSlice[1] = 123456 ​ fmt.Println(s1) ​ fmt.Println(reSlice) } ``` 我们使用`[:]`操作获取第2、3个元素。 > Tip: 假设有一个数组a1,你可以执行`s1 := a1[:]` 来创建一个引用a1的切片 将上述代码保存为`reslice.go`并执行,将得到以下输出; ```bash $ go run reslice.go [0 0 0 0 0] [0 0] [0 -100 123456 0 0 ] [-100 123456] ``` 可以看到切片s1的输出是[0 -100 123456 0 0 ],但是我们并没有直接改变s1。这说明通过re-slicing操作得到的切片,与原切片指向同一片内存地址! re-slicing操作的第二个问题是,只要较小的重新切片存在,来自原始切片的底层数组就会被保存在内存中,因为较小的重新切片引用了原始切片, 尽管你可能是想通过使用re-slicing从原切片中得到较小的一个切片,这对于小切片来说并不是什么严重问题,但是在这种情况下就可能导致bug:你将大文件的内容读到切片中,但是你只是想使用其中一小部分。