// Reset resets the Builder to be empty.
func (b *Builder) Reset() {
b.addr = nil
b.buf = nil
}
代码片段来自go字符串中的源代码。建设者缓冲区被设置为nil
而不是b.buf[:0]
。将其设置为nil
而不是保留容量的原因是什么?
EDIT:我可以看到Reset()
可以用于GC底层缓冲区,并允许重新使用Builder结构,但初始化结构似乎是一个边际成本,因为它只是两个指针,而底层数组可能更大,可以重新使用。我觉得应该有一个Clear()
函数来保持底层缓冲区的容量,但将其长度减少到0,而且实现起来很简单。这让我相信为什么没有这样做是有原因的,我很好奇这个原因是什么
strings.Builder
的优化之一是在将[]byte
转换为string
时不复制字节。看看它的String()
方法:
// String returns the accumulated string.
func (b *Builder) String() string {
return *(*string)(unsafe.Pointer(&b.buf))
}
这意味着重用缓冲区会破坏以前创建的字符串。
下面是操场上的证据:https://play.golang.org/p/gkSXRwi0-Ff
Reset()
的目的是使Builder
处于初始空状态(如创建新状态时(。
这样做而不是获得新的Builder
的好处是,当程序的其他组件持有对现有Builder
的引用,并且您希望将其"重置"为初始状态,而不使用新引用刷新所有这些组件时。
如果Reset
保留了底层缓冲区,那么一个长寿命的Builder
将占用它所构建的最长字符串的内存。为最长字符串分配的数组将始终处于活动状态,即使其中大部分未使用。将缓冲区设置为nil允许垃圾收集器收集这种潜在的大缓冲区。