Reputation: 33215
To get length of any slice, I use reflect.ValueOf(slice).Len()
.
To set length of any slice, I use reflect.ValueOf(&slice).Elem().SetLen(n)
.
I have a field of type reflect.Value
in my struct, and the value is set to be reflect.ValueOf(&slice)
so that I can change the slice. But now I can't get the length of the underlying slice.
It would panic because of call of reflect.Value.Len on ptr Value
if I call Len()
directly, and call of reflect.Value.Len on interface Value
if I call Elem().Len()
.
Below is the function I was trying to implement:
func pop(slice interface{}) interface{} {
v := reflect.ValueOf(slice)
length := v.Len()
last := v.Index(length - 1)
v.SetLen(length - 1)
return last
}
How can I do both with refect.Value
of the slice pointer?
Upvotes: 2
Views: 934
Reputation:
Write the function to work with a pointer to slice argument.
// pop removes and returns the last element from
// the slice pointed to by slicep.
func pop(slicep interface{}) interface{} {
v := reflect.ValueOf(slicep).Elem()
length := v.Len()
last := v.Index(length - 1)
v.SetLen(length - 1)
return last
}
Call it like this:
slice := []int{1, 2, 3}
last := pop(&slice)
fmt.Println(last) // prints 3
fmt.Println(slice) // prints [1 2]
Upvotes: 2