6 ms·
> Having interfaces be autoimplemented [...] it's just not what I'm used to and it restricts me from writing certain types of code without using dummy methods l
by rakoo 12y ago
> Having interfaces be autoimplemented [...] it's just not what I'm used to and it restricts me from writing certain types of code without using dummy methods like so to get static type safety.
There's a Go idiom for that. If you have
type Doer interface {
Do()
}
and a
type thing struct {
}
and you want to make sure that `thing`s implement `Doer`, just add this line:
var _ Doer = thing{}
_ is a special value that can be redefined at will, so the pattern can be used as many times as needed. From there, the meaning should be straightforward: _ is a `thing` that implements `Doer`, so the compiler will check it. You get to keep implicit interfaces, that you can make explicit as you need.
Apart from that, this post is really great; as someone "used" to Go and not at all to Rust this kind of impressions is always enlightening.
- Manishearth 12y agooo, that's an interesting pattern :)
- pcwalton 12y agoThere's still no solution for the cowboy/shape problem (where you want to have a single object that can implement Cowboy::draw() and Shape::draw()) though, presumably.
- infogulch 12y agoThe solution is to use more specific names. E.g. Cowboy.DrawGun(), Shape.DrawTo(canvas) Yes, sometimes this isn't an option when you want to satisfy the interface for two different libraries, but I've not seen this occur very often. More likely you're in control of one of the interfaces; so rename your method to be more descriptive.
- pcwalton 12y ago> Yes, sometimes this isn't an option when you want to satisfy the interface for two different libraries This is assumed in the description of the problem. Go has no solution for it. (Java doesn't either, but this is one of the things that C# got right over Java; it's unfortunate that Go has the same issue.)
- infogulch 12y agoYou skipped the important part of my statement: > , but I've not seen this occur very often. Sure, it's a problem in theory. Whether it's a problem in practice is a different question. I'd be interested to see examples of this problem in the wild.
- pcwalton 12y agoIt comes up enough on Stack Overflow to indicate it's a real problem people are hitting: http://stackoverflow.com/questions/2598009/method-name-collision-in-interface-implementation-java http://stackoverflow.com/questions/2598009/method-name-colli... http://stackoverflow.com/questions/4033329/multiple-interfaces-with-same-method-names http://stackoverflow.com/questions/4033329/multiple-interfac... http://stackoverflow.com/questions/11343238/java-implementing-multiple-interfaces-with-same-method-and-different-return-ty http://stackoverflow.com/questions/11343238/java-implementin... http://stackoverflow.com/questions/17484325/implementing-multiple-interfaces-having-same-method http://stackoverflow.com/questions/17484325/implementing-mul... http://stackoverflow.com/questions/9863835/two-interfaces-with-same-method-signature-implemented-in-java-class http://stackoverflow.com/questions/9863835/two-interfaces-wi... http://stackoverflow.com/questions/19959371/calling-same-method-name-from-two-different-interface-java http://stackoverflow.com/questions/19959371/calling-same-met... http://stackoverflow.com/questions/14290902/multiple-interface-in-java-having-same-method-name-and-varable-name http://stackoverflow.com/questions/14290902/multiple-interfa... etc. etc. I got bored after the first page of Google results :)
- tptacek 12y agoWhich one of these links should I click to see someone having an actual practical problem based on this issue? Nobody is debating whether people notice the issue exists.
- pcwalton 12y agoThe very first one has a comment: > I encountered such a case where a legacy "Address" class implemented Person and Firm interfaces that had a getName() method simply returning a String from the data model. A new business requirement specified that the the Person.getName() return a String formatted as "Surname, Given names". After much discussion, the data was re-formated in the database instead. – belwood Further down someone hit a similar issue with the getString() method in some of the Android frameworks.
- deleted 12y ago[deleted]
- doragcoder 12y agoYou can use object composition: http://play.golang.org/p/jyS38luYjM http://play.golang.org/p/jyS38luYjM Then make a Draw() method on the single object default to what you expect. The simple inline explanation is: type SingleObject struct { Cowboy Shape } Access is as follows to be unambiguous: Woody.Cowboy.Draw() Woody.Shape.Draw()
- TheDong 12y agoThe problem is that you can't differentiate SingleObject from CowboyObject and ShapeObject. They all are the same interface and can be passed into each other's methods, leading to a logical error.
- dilap 12y agoIt's not super elegant, but if you need to satisfy the same interface in two different ways, you can do it with a helper that gives a particular view into your class. https://play.golang.org/p/t0gjJHjU7y https://play.golang.org/p/t0gjJHjU7y Edit: another variation on the same idea: https://play.golang.org/p/FqSFpMKQuv https://play.golang.org/p/FqSFpMKQuv
- codezero 12y agoThis is cool. Do you know any blog posts or documentation or threads where this is discussed in more detail?
- rakoo 12y agoI came across this while reading bradfitz' camlistore code; I didn't see any extensive documentation or post about that. There is a paragraph in the faq (https://golang.org/doc/faq#guarantee_satisfies_interface https://golang.org/doc/faq#guarantee_satisfies_interface) and one in "Effective Go" (https://golang.org/doc/effective_go.html#blank_implements https://golang.org/doc/effective_go.html#blank_implements), but I couldn't find much more than that.