Here's what I think you want, written in (as far as I am able to) idiomatic Go:
That strikes me as terribly unmaintainable.
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.
Maybe I don't know what exactly you want.
The Foo and Bar in my example have quite different CheckStatus() methods because those two structs are quite different. If there were more similar, then you could share more code.
In the second example no, in the first example, if you want two types to conform to an interface, you need two types - Go interfaces require an implementation.
In real code this is not really a limitation - types require minimal boilerplate in Go, and the complete definition can be one line (e.g. type StringReply string). You can create them very easily, and wrap standard types in them (see the error type example NegativeSqrtError). I'm not too familiar with C# generics I'm afraid so am guessing as to what you want to do. Go already has support for generic maps and lists which can take any type or interface (as in your dictionary example), so that's not really a problem. Maybe someone else who knows both better will jump in.
If you wanted to treat two types (string and Customer) in Go as the same sort of thing (a Reply), you can do this with an interface. Then you can work with anything which conforms to that interface. Let's say you have this reply interface:
type Reply interface {
Reply() string
}
That requires a Reply method returning a string. You want to pass around both a string and a Customer (using say its name) as a reply? Define what each does when it replies - this is required so that the compiler knows you are passing the right sort of type, and so that you can actually use them as replies (NB you can't add to built-ins, so you have to add a new StringReply type): type Customer struct {Name string}
func (c *Customer) Reply() string {
return fmt.Sprintf("%s",c.Name)
}
type StringReply string
func (s StringReply) Reply() string {
return string(s)
}
http://play.golang.org/p/uLgSpbTx24so you could have a list []Reply or a map[string]Reply, or some custom collection type which can only have Replies added to it and nothing else.
If you want to reuse code between types, you can have helper methods or embedded types (NB only reusing code, not data, this is not inheritance).
Code above is trivial of course, and if you see code repeated in other examples it'll be because of these are little toy examples - you can use composition of types or helpers which act on interfaces to avoid repeating yourself. In real code you tend not to have quite such simple interfaces or types. If you feel we're not getting at what you want, posting a C# example of something you think would be impossible in Go would be helpful, otherwise you can assume that what most of what you can do in C# etc can easily be handled in Go as well even if the concepts don't map 1-1.
Reply<T>{
T ReplyData;
bool TheCallWorked;
string AssociatedMessage;
// other stuff here
}
and that's it - I can now have a reply that bundles up any type I like. My GetAddress function can return a Reply<Address>, my GetCustomerAge function can return a Reply<int>, etc.Whereas you're having me recreate that boilerplate for every different reply type - which means that if the information needed for a Reply changes, or I have to make a fix to the associated code, I need to change every instance of it.
You could reproduce your example above using a base reply type with ReplyData as an empty interface{} ptr (you'd have to wrap built-ins like int) and accessible fields. You could attach functions to that and only change them once and extend by embedding it in other special types of Reply if you wished. Typically though you'd have a base reply with bool and string say, and then extend that with other types of reply which make sense in certain situations rather than a generic payload which could be anything - so make ReplyData or a Reply type conform to an interface to ensure it does what your receiving methods want.
You can do the same things without them - but you have to write separate code for each type you deal with.