将切片扩展到其切片的最简单方法是什么?容量?

时间:2017-09-21 14:04:19

标签: go slice

我有一个程序使用缓冲池来减少代码中几个对性能敏感的部分的分配。

像这样:play link

// some file or any data source
var r io.Reader = bytes.NewReader([]byte{1,2,3})

// initialize slice to max expected capacity
dat := make([]byte, 20)

// read some data into it. Trim to length.
n, err := r.Read(dat)
handle(err)
dat = dat[:n]

// now I want to reuse it: 
for len(dat) < cap(dat) {
        dat = append(dat, 0) 
}

log.Println(len(dat))
// add it to free list for reuse later
// bufferPool.Put(dat)

我总是分配固定长度的切片,保证大于所需的最大尺寸。我需要将大小减小到实际数据长度才能使用缓冲区,但我还需要它再次作为最大大小,以便在下次需要时读入它。

我知道扩展切片的唯一方法是使用append,这就是我正在使用的。虽然这个循环感觉非常脏。而且可能效率低下。我的基准测试显示它并不可怕,但我觉得必须有更好的方法。

我只知道切片的内部表示,但如果我只能以某种方式覆盖长度值而不实际添加数据,那将是非常好的。我真的不需要把它归零或任何东西。

有没有更好的方法来实现这一目标?

3 个答案:

答案 0 :(得分:8)

&#34;延伸&#34;对其容量的切片只是slice expression,并将容量指定为高索引。高指数不需要小于长度。限制是:

  

对于数组或字符串,索引在0 <= low <= high <= len(a)范围内,否则它们超出范围。 对于切片,索引上限是切片容量cap(a) 而不是长度。

示例:

b := make([]byte, 10, 20)
fmt.Println(len(b), cap(b), b)

b = b[:cap(b)]
fmt.Println(len(b), cap(b), b)

输出(在Go Playground上尝试):

10 20 [0 0 0 0 0 0 0 0 0 0]
20 20 [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]

答案 1 :(得分:4)

您可以通过切片将切片扩展到其容量:

s = s[:cap(s)]

答案 2 :(得分:0)

  

使用 内置 copyappend函数,可以在此基础上完成许多操作。

请参阅:https://github.com/golang/go/wiki/SliceTricks#expand