Cast a struct pointer to interface pointer in Golang

41,623

There is no such thing as a "pointer to an interface" (technically, you can use one, but generally you don't need it).

As seen in "what is the meaning of interface{} in golang?", interface is a container with two words of data:

  • one word is used to point to a method table for the value’s underlying type,
  • and the other word is used to point to the actual data being held by that value.

interface

So remove the pointer, and doStuff will work just fine: the interface data will be &ms, your pointer:

func doStuff(inout interface{}) {
   ...
}

See this example:

ms := MyStruct{1}
doStuff(&ms)
fmt.Printf("Hello, playground: %v\n", ms)

Output:

Hello, playground: {1}

As newacct mentions in the comments:

Passing the pointer to the interface directly works because if MyStruct conforms to a protocol, then *MyStruct also conforms to the protocol (since a type's method set is included in its pointer type's method set).

In this case, the interface is the empty interface, so it accepts all types anyway, but still.

Share:
41,623
taharqa
Author by

taharqa

Updated on August 03, 2020

Comments

  • taharqa
    taharqa almost 4 years

    I have a function

    func doStuff(inout *interface{}) {
       ...
    }
    

    the purpose of this function is to be able to treat a pointer of any type as input. But when I want to call it with a the pointer of a struct I have an error.

    type MyStruct struct {
        f1 int
    }
    

    When calling doStuff

    ms := MyStruct{1}
    doStuff(&ms)
    

    I have

    test.go:38: cannot use &ms (type *MyStruct) as type **interface {} in argument to doStuff
    

    How can I cast &ms to be compatible with *interface{}?

  • newacct
    newacct over 9 years
    How interface variables work internally is not relevant to the question. Semantically an interface variable contains a copy of the value it was assigned from, just like any other type in Go. Underneath it's implemented with an immutable pointer to the data, but that's not visible to the programmer.
  • newacct
    newacct over 9 years
    You should explain that passing the pointer to the interface directly works because if MyStruct conforms to a protocol, then *MyStruct also conforms to the protocol (since a type's method set is included in its pointer type's method set). In this case, the interface is the empty interface, so it accepts all types anyway, but still.
  • VonC
    VonC over 9 years
    @newacct Good point. I have included your second comment in the answer for more visibility.
  • notzippy
    notzippy over 8 years
    It is also interesting to note that you can deal with pointers passed to functions by accessing the Type.Elem() function. This allows you to have a comparable for example reflect.TypeOf(&MyStruct{}).Elem() == reflect.TypeOf(MyStruct) See play.golang.org/p/DGb87RUZqJ