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

cap*_*aig 6 go slice

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

像这样:播放链接

// 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)
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

icz*_*cza 9

将切片"扩展"到其容量只是切片表达式,并将容量指定为高索引.高指数不需要小于长度.限制是:

对于数组或字符串,索引在范围内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)
Run Code Online (Sandbox Code Playgroud)

输出(在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]
Run Code Online (Sandbox Code Playgroud)


ANi*_*sus 9

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

s = s[:cap(s)]
Run Code Online (Sandbox Code Playgroud)