I just solved a similar problem in a slower but fairly general way. It's not appropriate everywhere, but it works well for the use-case I built it for.
I can't share the actual code, unfortunately, but by using struct field tags, reflect, and json, you can end up with code that looks something like this:
type FArgs struct {
A int `def:"11"`
B string `def:"\"some default\""`
}
func f(margs map[string]interface{}) {
var args FArgs
SetupArgs(margs, &args)
// ...
}
If f() is being called in a tight loop, your overhead can be enormous, but outside performance-critical code, it's probably good enough.