Этот коммит содержится в:
Damian Gryski 2023-02-25 17:30:48 -08:00 коммит произвёл Ayke
родитель 9b86080c80
коммит 836689fdd2
2 изменённых файлов: 63 добавлений и 2 удалений

Просмотреть файл

@ -958,10 +958,54 @@ func Copy(dst, src Value) int {
panic("unimplemented: reflect.Copy()") panic("unimplemented: reflect.Copy()")
} }
//go:linkname sliceGrow runtime.sliceGrow
func sliceGrow(buf unsafe.Pointer, oldLen, oldCap, newCap, elemSize uintptr) (unsafe.Pointer, uintptr, uintptr)
// extend slice to hold n new elements
func (v *Value) extendSlice(n int) {
if v.Kind() != Slice {
panic(&ValueError{Method: "extendSlice", Kind: v.Kind()})
}
var old sliceHeader
if v.value != nil {
old = *(*sliceHeader)(v.value)
}
var nbuf unsafe.Pointer
var nlen, ncap uintptr
if old.len+uintptr(n) > old.cap {
// we need to grow the slice
nbuf, nlen, ncap = sliceGrow(old.data, old.len, old.cap, old.cap+uintptr(n), v.typecode.elem().Size())
} else {
// we can reuse the slice we have
nbuf = old.data
nlen = old.len
ncap = old.cap
}
newslice := sliceHeader{
data: nbuf,
len: nlen + uintptr(n),
cap: ncap,
}
v.value = (unsafe.Pointer)(&newslice)
}
// Append appends the values x to a slice s and returns the resulting slice. // Append appends the values x to a slice s and returns the resulting slice.
// As in Go, each x's value must be assignable to the slice's element type. // As in Go, each x's value must be assignable to the slice's element type.
func Append(s Value, x ...Value) Value { func Append(v Value, x ...Value) Value {
panic("unimplemented: reflect.Append()") if v.Kind() != Slice {
panic(&ValueError{Method: "Append", Kind: v.Kind()})
}
oldLen := v.Len()
v.extendSlice(len(x))
for i, xx := range x {
v.Index(oldLen + i).Set(xx)
}
return v
} }
// AppendSlice appends a slice t to a slice s and returns the resulting slice. // AppendSlice appends a slice t to a slice s and returns the resulting slice.

Просмотреть файл

@ -117,6 +117,23 @@ func TestMap(t *testing.T) {
} }
} }
func TestSlice(t *testing.T) {
s := []int{0, 10, 20}
refs := ValueOf(s)
for i := 3; i < 10; i++ {
refs = Append(refs, ValueOf(i*10))
}
s = refs.Interface().([]int)
for i := 0; i < 10; i++ {
if s[i] != i*10 {
t.Errorf("s[%d]=%d, want %d", i, s[i], i*10)
}
}
}
func equal[T comparable](a, b []T) bool { func equal[T comparable](a, b []T) bool {
if len(a) != len(b) { if len(a) != len(b) {
return false return false