Stanislav
Stanislav

Reputation: 49

Why cant i pass a struct pointer with *interface{} parameter?

I can't find anything about *interface{} on google. So... The question is why these two approaches work differently?

package main

type MyStruct struct {}

func valI(x interface{}) {}
func pointI(x *interface{}) {}

func valS(s MyStruct) {}
func pointS(s *MyStruct) {}

func main() {
    s := MyStruct{}
    p := &s

    valI(s)
    valI(p) // Why? Success
    pointI(s) // Why?  Fail: cannot use s (type S) as type *interface {} in argument to point: *interface {} is pointer to interface, not interface
    pointI(p) // Why?  Fail: cannot use p (type *S) as type *interface {} in argument to point: *interface {} is pointer to interface, not interface

    valS(s)
    valS(p) // It's obvious to me why these two fail
    pointS(s) // -//-
    pointS(p)
}

Playground: https://play.golang.org/p/pio5vf-fBxH

Upvotes: 0

Views: 1104

Answers (1)

Burak Serdar
Burak Serdar

Reputation: 51577

An interface contains a pointer to the underlying data and type information. When you assign a non-interface value to an interface (or pass a non-interface value as an interface arg) the compiler generates code to pass the type and pointer to the underlying data. In a way, an interface is a struct:

type interface struct {
   Data pointer
   Type type
}

A pointer to an interface is simply a pointer to an instance of this struct.

All values satisfy the interface{} interface, so you can pass a struct or *struct where interface{} is required. *interface{} is a pointer to an interface, and only a pointer to an interface can be passed:

x:=interface{}(s)
pointI(&x)

Upvotes: 3

Related Questions