Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

I suppose they aren't that hairy if you introduce type-specific namespacing like C++ does; i.e. allowing method names to be qualified with the name of the class or trait they belong to to resolve conflicts (A::X and B::X). Renaming seems like a way to avoid having to create an extra delegation function in case you want to delegate to one or the other, though.

It's important to keep in mind that traits aren't the same as inheritance, though. Traits combine methods and fields into one final class instance (they're like mixins), while anonymous fields are more like C++ inheritance: there's actually an instance of each superclass embedded inside each subclass. This starts to matter especially when you have diamond patterns (A derives B and C, B and C derive D). When you have an instance of D and are calling methods of A on it, does each method of B's embedded A clash with that of C's embedded A in Go?



Go's anonymous fields are always accessible as a struct member named after their type, basically. It isn't namespacing, it's syntactic sugar that kinda-sorta removes their anonymity. Diamond inheritance in Go means you have physical nesting like [D [C [A]] [B [A]]] so necessarily the A's will clash, but you can override their methods and manually resolve it - yeah, at the cost of a delegating call (which the compiler could probably strip out).

Interfaces subsume the feature of traits to define an operation abstractly against the methods of its operand without defining its representation. Unlike traits though they can't mess with member variables directly (of course methods/interfaces can be defined on things that lack members, such as a renamed int32).


Traits are actually about code reuse, not about polymorphism. Indeed, in the original traits literature (and in Rust), traits are not types at all. You use interfaces in Rust for that, just as you do in Go (they work very similarly).

Think of traits as little pieces you can glue together to make a class.


Pure-code mixins and methods on Go interfaces are sort of duals of one another. Interface methods are parameterized with a type when called ("calling outwards"), mixins are parameterized by a type when compiled, and merged into it ("calling inwards").




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: