I am making a function that will unpack arbitrary variable types from a variadic parameter into variables like so:
package main
import (
"fmt"
)
func unpackVariadic(variadic []interface{}, into ...*interface{}) {
for i, v := range into {
*v = variadic[i]
}
}
func Update(variadic ...interface{}) {
var a, b interface{}
unpackVariadic(variadic, &a, &b)
a = "Hey"
b = "Hello"
}
func main() {
a, b := "Hola", "Hola"
Update(&a, &b)
fmt.Println(a)
fmt.Println(b)
}
However, it is printing "Hola", "Hola"
instead of "Hey", "Hello"
how I would like.
My understanding is that a
and b
in Update()
and main()
have different reference values, meaning reassigning from within Update()
will just locally assign a
and b
from the addresses of original a
and b
to the values of the new strings.
To solve this, I tried reassigning a
and b
by their object pointers:
func Update(variadic ...interface{}) {
var a, b *interface{}
unpackVariadic(variadic, a, b)
*a = "Hey"
*b = "Hello"
}
But, when I do, I get invalid operation: cannot indirect a (variable of type interface{})
.
So, why am I unable to assign by object pointers in Update()
while I am allowed to in unpackVariadic
? How could I go about this differently?
CodePudding user response:
Let's look at the variable types:
In Update(&a, &b)
, the values passed are *string
values. In unpackVariadic
, these two are assigned to two interface{}
variables, so they are both *string
as well.
When you do a = "Hey"
, you discard the *string
value in a
and reassign it to a string value. This assignment only changes the value of a
in unpackVariadic
, it does not change the values of the interfaces passed to it.
To change the values of slice arguments, do:
*a.(*string) = "Hey"
*b.(*string) = "Hello"
This will assign new values to the contents of a
and b
, instead of assigning a
and b
, thus, modifying the values passed in from main
.