完整切片符号 a[low : high : max] 的用处?
Posted
技术标签:
【中文标题】完整切片符号 a[low : high : max] 的用处?【英文标题】:Usefulness of the full slice notation a[low : high : max]? 【发布时间】:2020-04-27 20:49:21 【问题描述】:通过使用full slice notationb = a[low:high:max]
,可以获得容量小于分配的切片a
的切片。切片b
的容量将为max - low
,元素存储将与a
共享(不进行复制)。 max - low
必须小于或等于 cap(a)
,否则我们会感到恐慌:
a := make([]byte, 8)
b := a[:3:10]
panic: runtime error: slice bounds out of range [::10] with capacity 8
获得容量较小的切片的可能性有什么用?
我发现的唯一有用的应用程序是使用append
强制复制切片,从而绕过容量减少的切片的容量。
a := []int1, 2, 3, 4, 5
b := a[1:3:3]
fmt.Println("a:", a, "b:",b, "cap(b):", cap(b)) // -> a: [1 2 3 4 5] b: [2 3] cap(b): 2
b[0] = 6
fmt.Println("a:", a, "b:",b, "cap(b):", cap(b)) // -> a: [1 6 3 4 5] b: [6 3] cap(b): 2
b = append(b, 7) // copy slice elements and extends capacity of b
fmt.Println("a:", a, "b:",b, "cap(b):", cap(b)) // -> a: [1 6 3 4 5] b: [6 3 7] cap(b): 4
b[1] = 8
fmt.Println("a:", a, "b:",b, "cap(b):", cap(b)) // -> a: [1 6 3 4 5] b: [6 8 7] cap(b): 4
请注意,这样的副本并不明显,需要注释以使其对读者可见。
还有其他有用的应用吗?
【问题讨论】:
【参考方案1】:它确实在追加时强制复制,但它的作用稍微比这更通用。如果您使用它,您可以将切片传递给一些未知的代码,并且知道该代码将无法使用切片来读取或写入比您想要的更多的底层数组。
通过普通切片表达式创建的切片将具有足够的容量来到达从中切片的数组或切片的末尾,因此调用者可以将其重新切片到其容量以访问这些项目。完整的切片表达式使这不可能(或超出某个点不可能)。
这不是一个安全措施。您程序中的其他代码当然可以通过一种或另一种方式使用unsafe
确定如何读取或写入超出切片末尾的内容。这只是防止意外副作用的一种方法。如果您在您关心的某些数据的中间调用带有切片的函数,并且该函数可能append
以或以其他方式扩展切片,则使用完整切片表达式来限制容量是明智之举.
【讨论】:
它对运行时系统本身也很有用。例如,当您使用 cgo 通过 C 指针访问 C“数组”时,您会看到这渗入到您自己的非运行时系统代码中。这些跨语言函数位于“用户”代码与“系统运行时”代码的边缘。以上是关于完整切片符号 a[low : high : max] 的用处?的主要内容,如果未能解决你的问题,请参考以下文章