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