Reputation: 3146
I receive an interface which is basically a slice. Now I want to convert it to a pointer to the slice. The problem is, that I have either the slice itself or a Pointer to an interface. I can easily show in a code example:
func main(){
model := []int{1,2,3,4,5,6,7,8,10,11,133123123123}
method(model)
}
func method(model interface{}){
fmt.Println(reflect.TypeOf(model)) // this is of type []int
fmt.Println(reflect.TypeOf(&model)) // this is of type *interface{}
}
What I need is this type:
fmt.Println(reflect.TypeOf(result)) // this should be type *[]int
I know the type only on runtime, therefore I cannot just take
&(model.([]int))
Is there a way using golang reflection to receive this? the type 'int' is here actually not important, important is, that it is a Pointer to a slice. *[]interface{}
would be okay either.
Edit:
To make the question more clear, I should have added: I am not interested in the data of the slice, but only in getting a pointer to a slice of same type (which can basically be empty). Therefore James Henstridge answers works perfectly.
Upvotes: 5
Views: 3576
Reputation: 43949
Before trying to answer the question, it is worth stepping back and asking what the *[]int
value you're after should point at?
Given the way method
is called we can't possibly get a pointer to the model
variable from the calling context, since it will only receive a copy of the slice as its argument (note that this is a copy of the slice header: the backing array is shared).
We also can't get a pointer to the copy passed as an argument since it is stored as an interface{}
variable: the interface variable owns the memory used to store its dynamic value, and is free to reuse it when the a new value is assigned to it. If you could take a pointer to the dynamic value, this would break type safety if a different type is assigned.
We can obtain a *[]int
pointer if we make a third copy of the slice, but it isn't clear whether that's what you'd necessarily want either:
v := reflect.New(reflect.TypeOf(model))
v.Elem().Set(reflect.ValueOf(model))
result := v.Interface()
This is essentially a type agnostic way of writing the following:
v := new([]int)
*v = model
var result interface{} = v
Now if you really wanted a pointer to the slice variable in the calling context, you will need to ensure that method
is called with a pointer to the slice instead and act accordingly.
Upvotes: 6