Skip to content

Instantly share code, notes, and snippets.

@macrael
Last active August 31, 2017 02:12
Show Gist options
  • Select an option

  • Save macrael/9624de673f5c8087f03b3f68775cd041 to your computer and use it in GitHub Desktop.

Select an option

Save macrael/9624de673f5c8087f03b3f68775cd041 to your computer and use it in GitHub Desktop.
Exploring how interfaces interact with methods that have pointer receivers.
// Run this with go run.
package main
import "fmt"
type Counter interface {
bumpAndCount() int
sayMyName() string
}
type AnObject struct {
callCount int
name string
}
func (ao *AnObject) bumpAndCount() int {
fmt.Println("COUNTING", ao.callCount)
ao.callCount += 1
return ao.callCount
}
func (ao AnObject) sayMyName() string {
return ao.name
}
type AnValue struct {
callCount int
name string
}
func (av AnValue) bumpAndCount() int {
fmt.Println("VOUNTING", av.callCount)
av.callCount += 1
return av.callCount
}
func (av AnValue) sayMyName() string {
return av.name
}
// this is the part of this code that seems strange to me.
// Depending on wether you implemented the counter interface with a pointer receiver or a value receiver
// you pass either a pointer or a value to this function. The interface accepts both, but will only let you send
// the one that matches your interface.
// So, for AnObject, you must pass a pointer, but for AnValue you must pass a value
// Don't try and have the method take a *Counter, that's a pointer to the interface and apparenly never what you want.
// But why does it not care about sayMyName()? The pointer * seems to be a one way street.
func interfaceCounter(counter Counter) {
counter.bumpAndCount()
counter.bumpAndCount()
fmt.Println(counter.bumpAndCount())
fmt.Println(counter.sayMyName())
}
func pointerObjCounter(counter *AnObject) {
counter.bumpAndCount()
counter.bumpAndCount()
fmt.Println(counter.bumpAndCount())
fmt.Println(counter.sayMyName())
}
func valueObjCounter(counter AnObject) {
counter.bumpAndCount()
counter.bumpAndCount()
fmt.Println(counter.bumpAndCount())
fmt.Println(counter.sayMyName())
}
func valueValueCounter(counter AnValue) {
counter.bumpAndCount()
counter.bumpAndCount()
fmt.Println(counter.bumpAndCount())
fmt.Println(counter.sayMyName())
}
func main() {
fmt.Println("hello")
pointobj := &AnObject{name: "This object is passed by reference"}
valobj := AnObject{name: "This object is passed by value"}
valval := AnValue{name: "This value passed by value"}
interfaceCounter(pointobj)
valueObjCounter(*pointobj)
pointerObjCounter(pointobj)
interfaceCounter(&valobj)
valueObjCounter(valobj)
pointerObjCounter(&valobj)
valueValueCounter(valval)
interfaceCounter(valval)
interfaceCounter(&valval) // ...
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment