reflect: add Slice()
Этот коммит содержится в:
родитель
5cc5f11b58
коммит
43a4b256bd
2 изменённых файлов: 60 добавлений и 1 удалений
|
@ -382,7 +382,52 @@ func (v Value) Bytes() []byte {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v Value) Slice(i, j int) Value {
|
func (v Value) Slice(i, j int) Value {
|
||||||
panic("unimplemented: (reflect.Value).Slice()")
|
switch v.Kind() {
|
||||||
|
case Slice:
|
||||||
|
hdr := *(*sliceHeader)(v.value)
|
||||||
|
i, j := uintptr(i), uintptr(j)
|
||||||
|
|
||||||
|
if j < i || hdr.cap < j {
|
||||||
|
slicePanic()
|
||||||
|
}
|
||||||
|
|
||||||
|
elemSize := v.typecode.underlying().elem().Size()
|
||||||
|
|
||||||
|
hdr.len = j - i
|
||||||
|
hdr.cap = hdr.cap - i
|
||||||
|
hdr.data = unsafe.Add(hdr.data, i*elemSize)
|
||||||
|
|
||||||
|
return Value{
|
||||||
|
typecode: v.typecode,
|
||||||
|
value: unsafe.Pointer(&hdr),
|
||||||
|
flags: v.flags,
|
||||||
|
}
|
||||||
|
|
||||||
|
case Array:
|
||||||
|
// TODO(dgryski): can't do this yet because the resulting value needs type slice of v.elem(), not array of v.elem().
|
||||||
|
// need to be able to look up this "new" type so pointer equality of types still works
|
||||||
|
|
||||||
|
case String:
|
||||||
|
i, j := uintptr(i), uintptr(j)
|
||||||
|
str := *(*stringHeader)(v.value)
|
||||||
|
|
||||||
|
if j < i || str.len < j {
|
||||||
|
slicePanic()
|
||||||
|
}
|
||||||
|
|
||||||
|
hdr := stringHeader{
|
||||||
|
data: unsafe.Add(str.data, i),
|
||||||
|
len: j - i,
|
||||||
|
}
|
||||||
|
|
||||||
|
return Value{
|
||||||
|
typecode: v.typecode,
|
||||||
|
value: unsafe.Pointer(&hdr),
|
||||||
|
flags: v.flags,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
panic(&ValueError{"Slice", v.Kind()})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v Value) Slice3(i, j, k int) Value {
|
func (v Value) Slice3(i, j, k int) Value {
|
||||||
|
|
|
@ -133,6 +133,20 @@ func TestSlice(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
s28 := s[2:8]
|
||||||
|
s28ref := refs.Slice(2, 8)
|
||||||
|
|
||||||
|
if len(s28) != s28ref.Len() || cap(s28) != s28ref.Cap() {
|
||||||
|
t.Errorf("len(s28)=%d s28ref.Len()=%d cap(s28)=%d s28ref.Cap()=%d\n", len(s28), s28ref.Len(), cap(s28), s28ref.Cap())
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, got := range s28 {
|
||||||
|
want := int(s28ref.Index(i).Int())
|
||||||
|
if got != want {
|
||||||
|
t.Errorf("s28[%d]=%d, want %d", i, got, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
refs = MakeSlice(TypeOf(s), 5, 10)
|
refs = MakeSlice(TypeOf(s), 5, 10)
|
||||||
s = refs.Interface().([]int)
|
s = refs.Interface().([]int)
|
||||||
|
|
||||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче