Search code examples
functiongoargumentsparameter-passingpass-by-reference

Passing variables of different types by reference as arguments to same variadic parameter


I've been struggling with golang's lack of optional parameters, so I have been using the closest workaround: variadics. Even though I got it working, it is messy attempting to pass multiple variable types to the same variadic parameter by reference:

// back-end
func UpdateRef(variadic ...*interface{}) {
    for _, v := range variadic {
        if v.(type) == string {
            *v = "New ref val"
        }
    }
}

// front-end
func Interface(x interface{}) interface{} { return &x }
func main() {
    ref := Interface("Hey") // starts as "Hey"
    i := Interface(500)
    UpdateRef(&ref, &i) // ends at "New ref val"
}

If I replace the front-end with this:

// front-end
func main() {
    ref := "Hey" // starts as "Hey"
    UpdateRef(ref, 500) // ends at "New ref val"
}

...then how could I change the back-end to make the desired front-end code work? The back-end can be as verbose as need be, so long as the desired front-end runs as is. Is this possible? If not, is there an elegant solution that requires minimal changes to the desired front-end?


Solution

  • Use interface{} as the argument type. Type assert to pointer types. Dereference pointers to set the values.

    func UpdateRef(variadic ...interface{}) {
        for _, v := range variadic {
            if v, ok := v.(*string); ok {
                *v = "New ref val"
            }
        }
    }
    

    Pass pointers to the function:

    ref := "Hey"
    i := 500
    UpdateRef(&ref, &i)
    fmt.Println(ref)  // prints “New ref val”