> To be fair, you can do this in java by adding to Header and MIMEHeader "implements emailHeader".
Not if you aren't the author of the package. (You could modify your local copy, but requiring a fork is always a pain.) Without the ability to modify the sources, you would have to create custom subclasses of Header and MimeHeader which implement that interface, and find some way to make the library generate your custom subclasses instead of the defaults.
One potential downside is that it's a lot harder or more computationally expensive to figure out class/interface relationships in IDEs or other tools. (I haven't used Go, though, so I'm not sure what kinds of tools are available for it.)
Generally, "what classes implement this interface?" is a question I need to ask quite a bit when working with Java in Eclipse. The simple way in Go (looking through all classes) would generate a bunch of false positives in a large enough codebase, and the more precise way (looking through all implicit casts everywhere to find all classes that are implicitly casted to the interface) is probably pretty slow or memory intensive and could potentially have false negatives (e.g. implementing classes that haven't been hooked up yet, and uses that aren't contained in your source tree).
There are other Eclipse operations that rely on this that would also be a lot harder to implement (in the same way they're implemented in Eclipse):
-"Find callers" on a class method includes calls to that method on superclasses and superinterfaces.
-"Rename method" automatically renames all methods with that name that are reachable through a path of implementer/interface relationships.
There is another downside, and that is when interfaces are used to tag semantics. Say that I have classes that computes metric space distances. I could make an interface MetricSpace using a Distance method. However, in Go, every struct for which the Distance method is implemented with the same signature will implement the MetricSpace interface. In other languages with interfaces, only the types that are explicitly marked as implementing that interface will implement it.
Structuring typing seems simpler. Are there any downsides? (apart from two types having an identical method signature by coincidence)