Last active
August 31, 2017 02:12
-
-
Save macrael/9624de673f5c8087f03b3f68775cd041 to your computer and use it in GitHub Desktop.
Exploring how interfaces interact with methods that have pointer receivers.
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
| // 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