}
}
+func TestCopyString(t *testing.T) {
+ t.Run("Slice", func(t *testing.T) {
+ s := bytes.Repeat([]byte{'_'}, 8)
+ val := ValueOf(s)
+
+ n := Copy(val, ValueOf(""))
+ if expecting := []byte("________"); n != 0 || !bytes.Equal(s, expecting) {
+ t.Errorf("got n = %d, s = %s, expecting n = 0, s = %s", n, s, expecting)
+ }
+
+ n = Copy(val, ValueOf("hello"))
+ if expecting := []byte("hello___"); n != 5 || !bytes.Equal(s, expecting) {
+ t.Errorf("got n = %d, s = %s, expecting n = 5, s = %s", n, s, expecting)
+ }
+
+ n = Copy(val, ValueOf("helloworld"))
+ if expecting := []byte("hellowor"); n != 8 || !bytes.Equal(s, expecting) {
+ t.Errorf("got n = %d, s = %s, expecting n = 8, s = %s", n, s, expecting)
+ }
+ })
+ t.Run("Array", func(t *testing.T) {
+ s := [...]byte{'_', '_', '_', '_', '_', '_', '_', '_'}
+ val := ValueOf(&s).Elem()
+
+ n := Copy(val, ValueOf(""))
+ if expecting := []byte("________"); n != 0 || !bytes.Equal(s[:], expecting) {
+ t.Errorf("got n = %d, s = %s, expecting n = 0, s = %s", n, s[:], expecting)
+ }
+
+ n = Copy(val, ValueOf("hello"))
+ if expecting := []byte("hello___"); n != 5 || !bytes.Equal(s[:], expecting) {
+ t.Errorf("got n = %d, s = %s, expecting n = 5, s = %s", n, s[:], expecting)
+ }
+
+ n = Copy(val, ValueOf("helloworld"))
+ if expecting := []byte("hellowor"); n != 8 || !bytes.Equal(s[:], expecting) {
+ t.Errorf("got n = %d, s = %s, expecting n = 8, s = %s", n, s[:], expecting)
+ }
+ })
+}
+
func TestCopyArray(t *testing.T) {
a := [8]int{1, 2, 3, 4, 10, 9, 8, 7}
b := [11]int{11, 22, 33, 44, 1010, 99, 88, 77, 66, 55, 44}
// It returns the number of elements copied.
// Dst and src each must have kind Slice or Array, and
// dst and src must have the same element type.
+//
+// As a special case, src can have kind String if the element type of dst is kind Uint8.
func Copy(dst, src Value) int {
dk := dst.kind()
if dk != Array && dk != Slice {
dst.mustBeExported()
sk := src.kind()
+ var stringCopy bool
if sk != Array && sk != Slice {
- panic(&ValueError{"reflect.Copy", sk})
+ stringCopy = sk == String && dst.typ.Elem().Kind() == Uint8
+ if !stringCopy {
+ panic(&ValueError{"reflect.Copy", sk})
+ }
}
src.mustBeExported()
de := dst.typ.Elem()
- se := src.typ.Elem()
- typesMustMatch("reflect.Copy", de, se)
+ if !stringCopy {
+ se := src.typ.Elem()
+ typesMustMatch("reflect.Copy", de, se)
+ }
var ds, ss sliceHeader
if dk == Array {
ss.Data = src.ptr
ss.Len = src.Len()
ss.Cap = ss.Len
- } else {
+ } else if sk == Slice {
ss = *(*sliceHeader)(src.ptr)
+ } else {
+ sh := *(*stringHeader)(src.ptr)
+ ss.Data = sh.Data
+ ss.Len = sh.Len
+ ss.Cap = sh.Len
}
return typedslicecopy(de.common(), ds, ss)