Last active
March 18, 2020 19:52
-
-
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]
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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