Overloading
Introduction
In Go, one name means one function — AreaCircle, AreaRect. Vuka adds functions and methods that share a name and differ in their parameters.
You reach for overloading when the same operation applies to several types and one name reads better than several.
Declaring Overloads
This sample declares two area functions and three Add methods, then calls them:
func area(c Circle) float64 { return math.Pi * c.R * c.R }
func area(r Rect) float64 { return r.W * r.H }
func (c *Counter) Add(by int) { c.n += by }
func (c *Counter) Add(by string) { c.n += len(by) }
func (c *Counter) Add(a, b int) { c.n += a + b }
area(Circle{R: 1})
c.Add(2, 3)Choosing an Overload
Each call goes to the overload that best fits its arguments' static types: identical types first, then an untyped constant's default type (scale(2) picks int, scale(2.5) picks float64), then anything assignable. No match, or a tie, is an error listing the candidates.
What It Becomes
Each overload is named after its parameter types, the way Go names such functions, and each call is pointed at one:
| Vuka | Go |
|---|---|
func area(c Circle) | func areaCircle(c Circle) |
func area(r Rect) | func areaRect(r Rect) |
func (c *Counter) Add(a, b int) | func (c *Counter) AddIntInt(a, b int) |
func (c *Counter) Add(xs ...int) | func (c *Counter) AddInts(xs ...int) |
area(Circle{R: 1}), c.Add(2, 3) | areaCircle(Circle{R: 1}), c.AddIntInt(2, 3) |
How Names Are Built
A parameter's type is written as part of the name: int is Int, *Shape Shape, time.Time Time, []Order and ...Order Orders, map[string]int MapStringInt, any Any; a leading context.Context is left out when more follows (Update(ctx, t Typing) is UpdateTyping), and an overload taking nothing is area0.
A name the package already has, or that two overloads would share (total(o Order) and total(o *Order)), gets a number: totalOrder2.
A live component's Update overloads are the methods the session delivers messages to (UpdateNewMessage, Stateful Components). Vuka 0.x named overloads area__Circle; ui.IsUpdate still takes Update__T.
Naming an Overload for Go
To give Go code a name of your own for one overload, use @export:
@export("RectArea")
func area(r Rect) float64 { return r.W * r.H }Limitations
An overloaded method can't satisfy an interface method of the plain name, and generic functions can't be overloaded yet.