Reputation: 49
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
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