Reputation: 137
I want to pass a pointer to something into a function, without knowing its type at compile time, have the function write to it. Here's what I thought would work:
func foo(dest interface{}) {
switch (dest).(type) {
case *int:
fmt.Println("got int")
*dest = 1
// handle other cases...
}
}
However, calling this with an *int
input
func main() {
bar := 2
foo(&bar)
fmt.Println(bar) // expect 1
}
yields the compiler error
invalid indirect of dest (type interface {})
.
What am I doing wrong here?
Upvotes: 1
Views: 930
Reputation: 3063
This question seems a bit old, but I have come along a more general way to handle this using reflection, it's not as fast as other solutions but it works with any other types you pass to the function
func foo(dest interface{}) {
destVal := reflect.ValueOf(dest)
val := reflect.ValueOf(1)
if destVal.Kind() == reflect.Ptr && destVal.Elem().Kind() == val.Kind() {
if destElem := destVal.Elem(); destElem.CanSet() {
destElem.Set(val)
}
}
}
Upvotes: 0
Reputation: 1061
In this piece of code (btw, you don't need the parens around dest
), you are basically forgetting the type once you enter a case:
func foo(dest interface{}) {
switch dest.(type) {
case *int:
fmt.Println("got int")
*dest = 1
// handle other cases...
}
}
That is, dest is still of type interface{} according to the compiler, and that makes *dest = 1
wrong.
You could use more type assertions like this...
func foo(dest interface{}) {
switch dest.(type) {
case *int:
fmt.Println("got int")
*dest.(*int) = 1
// handle other cases...
}
}
...but a switch that actually 'remembers' the type would be much better (from Effective Go)
func foo(dest interface{}) {
switch dest := dest.(type) {
case *int:
fmt.Println("got int")
*dest = 1
// handle other cases...
}
}
Upvotes: 7
Reputation: 6877
dest is still of type interface{}
. You have to cast it during the assignment as well:
*dest.(*int) = 1
Upvotes: 1