通过使用full slice notation b = 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 := []int{1, 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请注意,这样的副本并不明显,需要注释才能让读者看到它。
其他的应用程序是否有用?
发布于 2020-01-10 16:55:55
它确实会强制在append上添加一个副本,但它所做的事情要比这稍微通用一些。如果您使用它,您可以将一个片段传递给一些未知的代码片段,因为该代码不能使用该片段来读取或写入比您所希望的更多的底层数组。
通过普通切片表达式创建的切片将具有足够的容量,足以到达从其切片的数组或切片的末尾,因此调用者可以将其重新切片到其容量,以获得对这些项的访问。一个完整的切片表达式使得这是不可能的(或者超过某个点是不可能的)。
这不是安全措施。您的程序中的其他代码肯定能够以某种方式知道如何使用unsafe读取或写入超过片末尾的内容。这只是一种防止意外副作用的方法。如果您正在调用一个函数,并在您关心的一些数据中间插入一个切片,并且该函数可能会对切片执行append操作或以其他方式扩展切片,那么使用完整切片表达式来限制容量是明智的做法。
https://stackoverflow.com/questions/59677677
复制相似问题