Fix slice next elem func

This commit is contained in:
Vladimir Mihailenco 2017-11-01 15:33:53 +02:00
parent 35248155a5
commit 48b70050d4
2 changed files with 28 additions and 12 deletions

View File

@ -120,8 +120,9 @@ func ScanSlice(data []string, slice interface{}) error {
return fmt.Errorf("redis: ScanSlice(non-slice %T)", slice) return fmt.Errorf("redis: ScanSlice(non-slice %T)", slice)
} }
next := internal.MakeSliceNextElemFunc(v)
for i, s := range data { for i, s := range data {
elem := internal.SliceNextElem(v) elem := next()
if err := Scan(internal.StringToBytes(s), elem.Addr().Interface()); err != nil { if err := Scan(internal.StringToBytes(s), elem.Addr().Interface()); err != nil {
return fmt.Errorf("redis: ScanSlice(index=%d value=%q) failed: %s", i, s, err) return fmt.Errorf("redis: ScanSlice(index=%d value=%q) failed: %s", i, s, err)
} }

View File

@ -28,20 +28,35 @@ func isLower(s string) bool {
return true return true
} }
func SliceNextElem(v reflect.Value) reflect.Value { func MakeSliceNextElemFunc(v reflect.Value) func() reflect.Value {
elemType := v.Type().Elem()
if elemType.Kind() == reflect.Ptr {
elemType = elemType.Elem()
return func() reflect.Value {
if v.Len() < v.Cap() {
v.Set(v.Slice(0, v.Len()+1))
elem := v.Index(v.Len() - 1)
if elem.IsNil() {
elem.Set(reflect.New(elemType))
}
return elem.Elem()
}
elem := reflect.New(elemType)
v.Set(reflect.Append(v, elem))
return elem.Elem()
}
}
zero := reflect.Zero(elemType)
return func() reflect.Value {
if v.Len() < v.Cap() { if v.Len() < v.Cap() {
v.Set(v.Slice(0, v.Len()+1)) v.Set(v.Slice(0, v.Len()+1))
return v.Index(v.Len() - 1) return v.Index(v.Len() - 1)
} }
elemType := v.Type().Elem() v.Set(reflect.Append(v, zero))
if elemType.Kind() == reflect.Ptr {
elem := reflect.New(elemType.Elem())
v.Set(reflect.Append(v, elem))
return elem.Elem()
}
v.Set(reflect.Append(v, reflect.Zero(elemType)))
return v.Index(v.Len() - 1) return v.Index(v.Len() - 1)
}
} }