reflect: add Append()
Этот коммит содержится в:
родитель
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
|
||||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче