I've encountered a rather curious situation in Go. Consider the code below:
type reader struct {
finished bool
}
func (r *reader) Read() {
fmt.Println("reading...")
r.finished = true
}
func main() {
r := reader{} // notice that r is not a pointer to a reader struct
r.Read() // works just fine
fmt.Println(r.finished) // true
}
What I think about the code above is that the method
func (r *reader) Read() {...}
is the same as
func Read(r *reader) {...}
so when I call the .Read()
method in a non-pointer reader
type go automatically does something like this:
r := reader{}
(&r).Read() // something like Read(&r)
Correct me if I'm wrong since this is merely my deduction.
But my actual question is that why the same scenario does not work if I try to declare Reader
interface type with the concrete type being reader
and the concrete value being an instance of the reader
struct, like below:
type Reader interface {
Read()
}
type reader struct {
finished bool
}
func (r *reader) Read() {...}
func main() {
var r Reader = reader{} // compile error
r.Read()
}
The compile error above states:
cannot use reader{} (value of type reader) as Reader value in variable declaration: reader does not implement Reader (method Read has pointer receiver)
Can anyone explain what's exactly going on under the hood? Why are the behaviors different for structs and interfaces?