aslanides
aslanides

Reputation: 137

go - function to write to an interface{}

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

Answers (3)

samix73
samix73

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)
        }
    }
}

example

Upvotes: 0

Evert Heylen
Evert Heylen

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

Per Johansson
Per Johansson

Reputation: 6877

dest is still of type interface{}. You have to cast it during the assignment as well:

*dest.(*int) = 1

Upvotes: 1

Related Questions