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