我正在学习 Go,现在开始研究数组和切片。我参考了《Effective Go》和《A Tour of Go》。我对切片容量的计算公式有些疑问。请参阅下面代码中的注释。
package main
import "fmt"
func main() {
// let's say I need to implement 5x5 picture with 2D slice
// and I have two ways to do that in acc. with
// https://go.dev/doc/effective_go#two_dimensional_slices
// that said:
// 1. six slices - six underlying arrays
picture := make([][]uint8, 5)
for i := range picture {
picture[i] = make([]uint8, 5)
}
// 2. six slices - two* underlying arrays
// *I THOUGHT the efficiency is hiding in number of arrays
picture = make([][]uint8, 5)
pixels := make([]uint8, 25)
for i := range picture {
// every iteration pixels[5:] allocates new array...
picture[i], pixels = pixels[:5], pixels[5:]
// ...but in the new iteration it's deleted
// leaving slice of initial pixels array in picture[i]...
}
// ...and here we have only two arrays...
// ... ^^^ B5t ^^^
// there are six arrays anyway
// but their capacity is 5 for picture and
// 25, 20...5 respectively for its contents
fmt.Print(cap(picture), " ")
for i := range picture {
fmt.Print(cap(picture[i]), " ")
}
fmt.Println()
// if you don't understand let me explain my position
// capacity is characteristic of underlying array rather than
// of slice itself
// in acc. with https://go.dev/tour/moretypes/11
// "The capacity of a slice is the number of
// elements in the underlying array..."
// I believe that capacity of array is immutable one and
// one array cannot have different cap's at the same time
picture = make([][]uint8, 5)
for i := range picture {
picture[i] = make([]uint8, 5)
}
// here we have six arrays but capacity of each is 5
// so the first solution works efficiently than second one
// I believe
fmt.Print(cap(picture), " ")
for i := range picture {
fmt.Print(cap(picture[i]), " ")
}
fmt.Println()
}
该代码的输出是:
5 25 20 15 10 5
5 5 5 5 5 5
有人可以解释一下使用一种分配方法的效率隐藏在哪里吗?