3 ms·
Let's say we have a Reply<T> which packages up the actual reply from a service, along with the status of the service call, and any additional warnings, etc. In
by AndrewDucker 14y ago
Let's say we have a Reply<T> which packages up the actual reply from a service, along with the status of the service call, and any additional warnings, etc.
In C# I can define this once, and then any service can just return a Reply<string>, Reply<int>, Reply<Address>, etc. The calling method can check the associated reply status, and then unwrap the data if the call was successful, displaying any associated messages as needed.
Or, for a different example: If I want to store a long list of Customers in a dictionary, keyed on String, then in C# I'd create a Dictionary<string,Customer>, and know that it would always contain the types I'd expect.
How would I do either of those in Go?
- grey-area 14y agoI'm no expert in Go, but I think it can cover most common uses of generics like those you mention, though you cannot of course replicate all C++ code in Go without changing paradigms a little. It won't work in exactly the same way, but it can usually solve the same problems elegantly. 1. Generic reply (for a good example of this in use see the way errors are used in go; errors are extensible and can contain info like that in your example). http://blog.golang.org/2011/07/error-handling-and-go.html http://blog.golang.org/2011/07/error-handling-and-go.html For your example, you could have a reply interface, defining the requirements, then concrete types which conform: http://play.golang.org/p/e18n36Ub5u http://play.golang.org/p/e18n36Ub5u There are probably shorter ways to do this, this is just an off the cuff example, but it's quite possible to have generic reply types which respond to any methods you want, and can be created easily and extended if necessary. You can also cast back to the original type. 2. Just use map[string]Customer - Customer could be an interface (duck typing) or a type. Something like this: http://play.golang.org/p/ZoftbY8mQX http://play.golang.org/p/ZoftbY8mQX IMHO using an interface here is more interesting, as it lets you define your requirements, and forget all about the type system, while letting the compiler check that any uses will always work as they conform to the interface.
- AndrewDucker 14y agoIn your examples there, am I not having to create a new type per case? So a Reply<String> and a Reply<Customer> will require me to create two classes?
- ansible 14y agoYou'd just want to have your types implement the interface for Reply, and provide a method with the same signature that clients can use. Here's what I think you want, written in (as far as I am able to) idiomatic Go: http://play.golang.org/p/KI79ynfRg2 http://play.golang.org/p/KI79ynfRg2
- quatrevingts 14y agoThis means that your objects are aware of every "container" that might hold them. This does not scale, and it certainly doesn't work for reusing data structures.
- Evbn 14y agoIt scales in the sense that all types are extensible: you can make A implement B by adding the appropriate definitions anywhere, not just in the file that defines B. Rubyists call this monkey patching and they love it (but Ruby monkey patching can do wackier things beyond adding new methods)
- quatrevingts 14y agoBut I can only make A implement B in the file that defines A, at least according to the comments here: https://news.ycombinator.com/item?id=5443344 https://news.ycombinator.com/item?id=5443344
- AndrewDucker 14y agoSo every type that can be returned from a service call has to implement Reply? That's acres of template code being duplicated all over the place - and if I need to fix a defect in it I need to change it in every place! That strikes me as terribly unmaintainable.
- grey-area 14y agoSo every type that can be returned from a service call has to implement Reply? Yes, if you want it to actually be a Reply, it has to implement Reply. That's acres of template code being duplicated all over the place No, if you need to reuse code you can use other techniques like embedding (not shown in examples). The features and restrictions differ from many other OO languages but I think the creators of Go deserve a little more credit than you are giving them - they do not produce unmaintainable code (see std lib for Go), worked on a large scale with C++ OOP previously, designed the forking Unix operating system, and are not unaware of the ramifications of the decisions taken.