返回介绍

03.3.1 切片基本操作

发布于 2024-08-14 12:50:32 字数 5841 浏览 0 评论 0 收藏 0

使用下面的代码可创建一个切片字面量:

aSliceLiteral := []int{1, 2, 3, 4, 5}

与定义数组相比,切片字面量只是没有指定元素数量。如果你在[]中填入数字,你将得到的是数组。

也可以使用 make() 创建一个空切片,并指定切片的长度和容量。容量这个参数可以省略,在这种情况下容量等于长度。

下面定义一个长度和容量均为20的空切片,并且在其需要的时候会自动扩容:

integer := make([]int, 20)

Go自动将空切片的元素初始化为对应元素的零值,意味着切片初始化时的值是由切片类型决定的。

使用下面的代码遍历切片中的元素:

for i :=0; i < len(integer); i++ {
  fmt.Println(i)
}

切片变量的零值是 nil, 下面代码可将已有的切片置为空:

aSliceLiteral = nil

可以使用 append() 函数追加元素到切片,此操作将触发切片自动扩容。

integer = append(integer, -5900)

integer[0] 代表切片integer的第一个元素,integer[len(integer)-1] 代表最后一个元素。

同时,使用[:]操作可以获取连续多个元素,下面的代码表示获取第2、3个元素:

integer[1:3]

[:]操作也可以帮助你从现有的切片或数组中创建新的切片或数组:

s2 := integer[1:3]

这种操作叫做re-slicing,在某种情况下可能会导致bug:

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个元素。

假设有一个数组a1,你可以执行 s1 := a1[:] 来创建一个以a1为引用的切片

将上述代码保存为 reslice.go并执行,将得到以下输出;

$ 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从原切片中得到较小的一个切片,但是原切片的底层数组仍然会跟随着re-slicing得到的小切片,这对于小切片来说并不是什么严重问题,但是在这种情况下就可能导致bug:你将大文件的内容读到切片中,但是你只是想使用其中一小部分。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文