Reputation: 1916
I thought this is a simple thing to do, but I was wrong. I can't pass integer
as pointer to function using interface{}
.
Example:
var test int
someChange(&test)
fmt.Printf("after function: %d", test)
func someChange(i interface{}) error{
newFunnyValue := 42
i = newFunnyValue
fmt.Printf("hello from someChange now value test is: %d" , i)
return nil //change gone ok, so nil
}
And result:
hello from someChange now value test is: 42
after function: 0
I read that interface{}
is similar to void*
so above code should work but it's not, why? I want to add that if I pass some object which is a struct, everything works good.
Do I have to wrap int
in some struct?
Edit:
https://play.golang.org/p/rg1vabug0P
Upvotes: 2
Views: 2164
Reputation: 417642
If you want to observe the change outside of the someChange()
function (in the test
variable), you must modify the pointed value (assign a new value to it). You're not doing that, you just assign a new value to the i
parameter (which is a local variable inside someChange()
).
You may obtain the *int
pointer from the i
interface variable using type assertion, and then you can assign a new value to the pointed value.
Example:
func someChange(i interface{}) error {
newFunnyValue := 42
if p, ok := i.(*int); ok {
*p = newFunnyValue
return nil //change gone ok, so nil
}
return errors.New("Not *int")
}
Testing it:
var test int
someChange(&test)
log.Printf("after function: %d", test)
Output (try it on the Go Playground):
2009/11/10 23:00:00 after function: 42
Note that wrapping the int
value or the *int
pointer in a struct is unnecessary and it wouldn't make a difference if you're not assigning a new value to the pointed object.
Upvotes: 3
Reputation: 7990
i
is still of type interface{}
within the func someChange()
. You have to cast it during the assignment:
*i.(*int) = 42
Upvotes: 1