> The standard http library was calling Close on my io.Reader. This is not expected behaviour when the interface clearly just takes an io.Reader (which exposes one and only one method Read).
So if I implemented my own object with a Reader interface and passed it to this HTTP library, could it find some other method on my object named Close() and it could call it?
Is it pure duck typing happening here, or is the HTTP library looking for a commonly-defined interface with documented semantics for Close()?
> So if I implemented my own object with a Reader interface and passed it to this HTTP library, could it find some other method on my object named Close() and it could call it?
Yes, and that's what's happening here. It can try to convert your value to a value of type Closer, which is an interface that implements a method Close(), and it can use that method. This conversion will succeed if the value you pass in has a method Close() (taking no arguments) -- Go has a strong "loose coupling" philosophy; there is no "implements."
For example, you can do:
nfoo, ok := foo.(myCustomInterface)
where foo is any value. If foo implements myCustomInterface (indicated by ok being True), regardless of whether that interface is exported or not, or whether the person behind foo intended to implement it, then you will be able to call myCustomInterface's methods on nfoo. It's not exactly duck typing, but it does mean that taking a value implementing SomeInterface is no guarantee that you can only use the methods defined by SomeInterface.
In Go, a type doesn't have to declare that it implements an interface; it automatically satisfies an interface if it implements the appropriate methods. Most interfaces in Go only contain one method.
If a type has a Close() method, then it is a Closer. The code that tries to cast it to a Closer will succeed. So to answer your question, it doesn't matter what the semantics of your Close() method are, it will succeed solely based on the fact that your type has a method with that name.
So if I implemented my own object with a Reader interface and passed it to this HTTP library, could it find some other method on my object named Close() and it could call it?
Is it pure duck typing happening here, or is the HTTP library looking for a commonly-defined interface with documented semantics for Close()?