Skip to content

Instantly share code, notes, and snippets.

@mtilson
Last active March 18, 2020 19:52
Show Gist options
  • Save mtilson/a658e1922f06bc45ee74e55576a7bc71 to your computer and use it in GitHub Desktop.
Save mtilson/a658e1922f06bc45ee74e55576a7bc71 to your computer and use it in GitHub Desktop.
how compiler implicitly makes reference and dereferences receiver argument for method call expression and how this influences interface satisfaction [golang]
// https://play.golang.org/p/Nolp4FTyp9I
package main
import "fmt"
type T struct {}
func (*T) String() string { // receiver parameter has type *T
return ""
}
type V struct {}
func (V) String() string { // receiver parameter has type V
return ""
}
func main() {
//var _ = T{}.String()
// cannot call pointer method on T literal \n cannot take the address of T literal
//var s *T ; var _ = s.String() // ok
// receiver argument has type *T, receiver parameter has type *T
//var s T ; var _ = s.String() // ok
// receiver argument has type T, receiver parameter has type *T
// compiler implicitly takes the address of the variable: (&s).String()
//var s *T; var _ fmt.Stringer = &s ; var _ = s.String()
// cannot use &s (type **T) as type fmt.Stringer in assignment: **T does not implement fmt.Stringer (missing String method)
//var s T; var _ fmt.Stringer = &s ; var _ = s.String() // ok 1
//var s *T; var _ fmt.Stringer = s ; var _ = s.String() // ok 2 - the same as ok 1 above
//var s T; var _ fmt.Stringer = s ; var _ = s.String()
// cannot use s (type T) as type fmt.Stringer in assignment: T does not implement fmt.Stringer (String method has pointer receiver)
//var _ = V{}.String() // ok
//var v *V = &V{}; var _ = v.String() // ok
// receiver argument has type *V, receiver parameter has type V
// compiler implicitly dereferences the receiver: (*v).String()
// var v *V = nil; var _ = v.String() // panic: runtime error: invalid memory address or nil pointer dereference
// var v *V; var _ = v.String() // panic: runtime error: invalid memory address or nil pointer dereference
//var v V; var _ = v.String() // ok
//var v *V; var _ fmt.Stringer = &v ; var _ = v.String()
// cannot use &v (type **V) as type fmt.Stringer in assignment: **V does not implement fmt.Stringer (missing String method)
//var v V; var _ fmt.Stringer = &v ; var _ = v.String() // ok 1
//var v *V = &V{}; var _ fmt.Stringer = v ; var _ = v.String() // ok 2 - the same as ok 1 above
// var v *V; var _ fmt.Stringer = v ; var _ = v.String() // panic: runtime error: invalid memory address or nil pointer dereference
//var v V; var _ fmt.Stringer = v ; var _ = v.String() // ok 3
// compiler implicitly takes the address of the variable (&v), as fmt.Stringer's String method has pointer receiver
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment