为什么不字符串.Builder Reset()是否保留基础缓冲区


// 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允许垃圾收集器收集这种潜在的大缓冲区。

最新更新