3 ms·
You're probably not still looking for an answer, but since I tried to work through this question myself I will answer it, if only for my own benefit: See the "
by hundt 7y ago
You're probably not still looking for an answer, but since I tried to work through this question myself I will answer it, if only for my own benefit:
See the "Mutually referencing type parameters" example. [0] Ignoring the issue of generic types vs functions, suppose you wanted to do shortest path as a fuction using the Node and Edge types described. You could try to write something like
func ShortestPath(type N implements Node, E implements Edge)(from, to N) []E
but how would it be implemented? Type N only promises that it it implements the Node interface which is just
Edges() []Edge
but those Edges might not be concrete type E.
So instead you must resort to
func ShortestPath(from, to Node) []Edge
and use type assertions, which is where we were before generics.
The contracts allow you to constraint the relationship between the concrete types N and E, enabling callers to work with concrete types directly.
[0] https://github.com/golang/proposal/blob/4a54a00950b56dd0096482d0edae46969d7432a6/design/go2draft-contracts.md#mutually-referencing-type-parameters https://github.com/golang/proposal/blob/4a54a00950b56dd00964...
- MrBuddyCasino 7y ago> You're probably not still looking for an answer On the contrary! I think I got it, thanks. Not sure which version is simpler though, I've certainly never hit the "Mutually referencing type parameters" issue before. I guess using concrete types and avoiding vtable lookups is an advantage that matters to Go?
- hundt 7y ago> I've certainly never hit the "Mutually referencing type parameters" issue before. I don't think I have either, but according to that document supporting this use case was considered a minimum requirement for generics. I don't know that much about generics but maybe it comes up more often than we realize. > I guess using concrete types and avoiding vtable lookups is an advantage that matters to Go? It avoids the vtable lookups and also, in cases like the mutually referencing type parameters, provides compile-type type-checking, which you don't get with the interface-only solution. I'm also not sure how your proposed solution extends to parameterized types. Certainly a central motivation of generics is make something like LinkedList<T> possible.