mirror of
https://github.com/golang/go
synced 2024-11-24 05:30:24 -07:00
strings: align Clone output with string([]byte(""))
Add a comment how strings of length 0 are treated and that they always will result in the return of a string equal to the constant string "". The previous implementation would return a string header that uses runtime.zerobase as the backing array pointer while the string constant "" has 0 as pointer value. Using 0 has the backing array pointer is also the behaviour of string([]byte(input)) which makes the new behaviour a better drop in replacement. Change-Id: Ic5460e9494b6708edbdfa4361e878d50db54ba10 Reviewed-on: https://go-review.googlesource.com/c/go/+/360255 Trust: Martin Möhrmann <martin@golang.org> Run-TryBot: Martin Möhrmann <martin@golang.org> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Russ Cox <rsc@golang.org>
This commit is contained in:
parent
4056934e48
commit
82f902ae8e
@ -16,7 +16,12 @@ import (
|
||||
// overuse of Clone can make programs use more memory.
|
||||
// Clone should typically be used only rarely, and only when
|
||||
// profiling indicates that it is needed.
|
||||
// For strings of length zero the string "" will be returned
|
||||
// and no allocation is made.
|
||||
func Clone(s string) string {
|
||||
if len(s) == 0 {
|
||||
return ""
|
||||
}
|
||||
b := make([]byte, len(s))
|
||||
copy(b, s)
|
||||
return *(*string)(unsafe.Pointer(&b))
|
||||
|
@ -11,9 +11,13 @@ import (
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
var emptyString string
|
||||
|
||||
func TestClone(t *testing.T) {
|
||||
var cloneTests = []string{
|
||||
"",
|
||||
strings.Clone(""),
|
||||
strings.Repeat("a", 42)[:0],
|
||||
"short",
|
||||
strings.Repeat("a", 42),
|
||||
}
|
||||
@ -25,9 +29,14 @@ func TestClone(t *testing.T) {
|
||||
|
||||
inputHeader := (*reflect.StringHeader)(unsafe.Pointer(&input))
|
||||
cloneHeader := (*reflect.StringHeader)(unsafe.Pointer(&clone))
|
||||
if inputHeader.Data == cloneHeader.Data {
|
||||
if len(input) != 0 && cloneHeader.Data == inputHeader.Data {
|
||||
t.Errorf("Clone(%q) return value should not reference inputs backing memory.", input)
|
||||
}
|
||||
|
||||
emptyHeader := (*reflect.StringHeader)(unsafe.Pointer(&emptyString))
|
||||
if len(input) == 0 && cloneHeader.Data != emptyHeader.Data {
|
||||
t.Errorf("Clone(%#v) return value should be equal to empty string.", inputHeader)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user