// String returns the accumulated string.
func (b *Builder) String() string {
- return *(*string)(unsafe.Pointer(&b.buf))
+ return unsafe.String(unsafe.SliceData(b.buf), len(b.buf))
}
// Len returns the number of accumulated bytes; b.Len() == len(b.String()).
}
b := make([]byte, len(s))
copy(b, s)
- return *(*string)(unsafe.Pointer(&b))
+ return unsafe.String(&b[0], len(b))
}
package strings_test
import (
- "reflect"
"strings"
"testing"
"unsafe"
t.Errorf("Clone(%q) = %q; want %q", input, clone, input)
}
- inputHeader := (*reflect.StringHeader)(unsafe.Pointer(&input))
- cloneHeader := (*reflect.StringHeader)(unsafe.Pointer(&clone))
- if len(input) != 0 && cloneHeader.Data == inputHeader.Data {
+ if len(input) != 0 && unsafe.StringData(clone) == unsafe.StringData(input) {
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)
+ if len(input) == 0 && unsafe.StringData(clone) != unsafe.StringData(emptyString) {
+ t.Errorf("Clone(%#v) return value should be equal to empty string.", unsafe.StringData(input))
}
}
}
// unsafeString converts a []byte to a string with no allocation.
// The caller must not modify b while the result string is in use.
unsafeString := func(b []byte) string {
- return *(*string)(unsafe.Pointer(&b))
+ return unsafe.String(unsafe.SliceData(b), len(b))
}
lengths := make([]int, 0) // lengths to test in ascending order
}
orig := "Input string that we expect not to be copied."
m = Map(identity, orig)
- if (*reflect.StringHeader)(unsafe.Pointer(&orig)).Data !=
- (*reflect.StringHeader)(unsafe.Pointer(&m)).Data {
+ if unsafe.StringData(orig) != unsafe.StringData(m) {
t.Error("unexpected copy during identity map")
}