3 ms·
What have’t we done. Attached that behavior to the struct itself so that invoking a struct's "area" function could give any of several different behaviors depe
by kd0amg 12y ago
What have’t we done.
Attached that behavior to the struct itself so that invoking a struct's "area" function could give any of several different behaviors depending on exactly what "rect" struct you have.
- jerf 12y agoTo do that in Go, you just add: type Area interface { area() int } though I'd note I'm deliberately just copying the article as written, as an "area" that's confined to an int is awfully weird. Note you can indeed just add that, and you're able to take "Area"s anywhere you like, and you can even do it in a different module entirely; nothing has to "declare" than a rect implements Area. To forstall the usual next question, no, Go has no further overloading based on type or anything else. My personal advice if you want to use that a lot is to use a different language. I like Go, but I look on the people trying to use it for machine learning or matrix math or other intensely mathematical computational loads with a bit of mystification. It isn't what it's good for, and I see no sign the core devs even consider it a marginal use case (to say nothing of a core use case) and have no intentions of changing the language to make this easier. If you really, really need overloading for your core use case, pick something else. Go is built for the environments where overloading is generally dangerous and used by people to do excessively "clever" things on the server, not for the environments where it is necessary. (Or perhaps "environment", singular, since "intensely mathematical code" is the only such thing I know of; everywhere else I've ever seen it it's asking for trouble.)
- rakoo 12y ago> Go has no further overloading based on type or anything else You can overload in Go: see for example how a zlib compressor is implemented [0]. The gist is that you take a standard io.Writer, embed it in your struct, and override the Write() method. This way you have a new io.Writer you can use wherever a io.Writer is needed. This pattern is actually standard in Go (and I guess in other languages where interfaces are more important than implementations) Or maybe I didn't understand ? [0] http://golang.org/src/pkg/compress/zlib/writer.go?s=4340:4391#L136 http://golang.org/src/pkg/compress/zlib/writer.go?s=4340:439...
- mseepgood 12y agoYou confound the two orthogonal terms "overloading" and "overriding". Overriding: class Foo { void f() {} } class Bar : Foo { void f() {} } Overloading: class Foo { void f(int i) {} void f(string s) {} } Go doesn't allow overloading: "method lookup is always by name only, not by signature (type) of the method. In other words, a single type can never have two methods with the same name. Given a method x.M, there's only ever one M associated with x. Again, this makes it easy to identify which method is referred to given only the name. It also makes the implementation of method invocation simple." http://talks.golang.org/2012/splash.article#TOC_11 http://talks.golang.org/2012/splash.article#TOC_11.
- jerf 12y agoThat's embedding. If it's a replacement for any traditional OO concept, it's "inheritance", not overloading. (It isn't a replacement, but if you found yourself needing inheritance, embedding is what you'd use to get the closest.) Overloading would allow multiple definition of the same function name that are dispatched in various ways based on the types being called. I show this only for example because it's horrifying Go code, but the closest go equivalent would be: func OverloadedSomething(params ...interface{}) interface{} { // (int, int) int if len(params) == 2 { a, isAInt := params[0].(int) b, isBInt := params[1].(int) if isAInt && isBInt { return a + b } } // (string) string if len(params) == 1 { aStr, isAStr := params[0].(string) if isAStr { return aStr + " world" } } // etc etc panic("OverloadedSomething not given something it can resolve") } Which could then be called like: sum := OverloadedSomething(1, 2).(int) helloWorld := OverloadedSomething("hello").(string) I may have the ... on the wrong side of the interface{} in the params. The Go thing to do is to declare separate functions for each implementation. Other languages have support for doing that sort of resolution at compile time, so you don't get the obvious run-time hit you'd take trying to do that in Go.