A lightweight argument checker to simulate function overloading in Golang.
Go does not support function or method overloading. One common workaround is using variadic parameters:
func Foo(args ...interface{}) interface{} {
// Process args
}
While flexible, this approach sacrifices type safety and often leads to repetitive, error-prone argument checking. This package provides tools to simplify that process.
Another alternative is to use a map[string]interface{}
for named arguments:
func Bar(arg map[string]interface{}) interface{} {
// Process arg
}
This package supports both approaches, offering helpers to validate positional and named arguments.
⚠️ Note: Variadic overloading is a powerful but debatable technique in Go. Use it wisely and sparingly.
Support for multiple type signatures:
package main
import (
ov "github.com/cwchentw/overloading-golang"
"log"
)
var checker *ov.ListChecker
func init() {
checker = ov.NewListChecker(
ov.NewListRule(
ov.NewArgument("int"),
ov.NewArgument("int")),
ov.NewListRule(
ov.NewArgument("float64"),
ov.NewArgument("float64")),
)
}
func main() {
n := add(3, 2).(int)
if n != 5 {
log.Fatal("Incorrect result")
}
}
func add(args ...interface{}) interface{} {
out := checker.Check(args)
switch out[0].(type) {
case int:
return out[0].(int) + out[1].(int)
case float64:
return out[0].(float64) + out[1].(float64)
default:
panic("Unsupported type")
}
}
Support for default values:
package main
import (
ov "github.com/cwchentw/overloading-golang"
"log"
)
var checker *ov.ListChecker
func init() {
checker = ov.NewListChecker(
ov.NewListRule(
ov.NewArgument("int"),
ov.NewArgument("int", 3)),
)
}
func main() {
n := add(3)
if n != 6 {
log.Fatal("Incorrect result")
}
}
func add(args ...interface{}) int {
out := checker.Check(args)
return out[0].(int) + out[1].(int)
}
Support for named parameters using maps:
package main
import (
ov "github.com/cwchentw/overloading-golang"
"log"
"reflect"
)
var checker *ov.MapChecker
func init() {
checker = ov.NewMapChecker(
ov.NewMapRule(
"x", ov.NewArgument("int"),
"y", ov.NewArgument("int")),
ov.NewMapRule(
"x", ov.NewArgument("float64"),
"y", ov.NewArgument("float64")),
)
}
func main() {
arg := map[string]interface{}{ "x": 3.0, "y": 2.0 }
n := add(arg).(float64)
if n != 5.0 {
log.Fatal("Incorrect result")
}
}
func add(arg map[string]interface{}) interface{} {
out := checker.Check(arg)
switch reflect.TypeOf(out["x"]).String() {
case "int":
return out["x"].(int) + out["y"].(int)
case "float64":
return out["x"].(float64) + out["y"].(float64)
default:
panic("Unsupported type")
}
}
MIT License Copyright (c) 2017 Modified and maintained by ByteBard