I want to replace an interface's value like this:
package main
import "fmt"
type Fooer interface {Foo(string)}
type Foo struct {foo string}
func (f *Foo) Foo(bar string) {f.foo = bar}
var z = &Foo{foo : "new"}
func swap(fooer Fooer) {fooer = z}
func main() {
f := &Foo{foo: "old"}
fmt.Printf("%s (want &{old})\n", f)
swap(f)
fmt.Printf("%s (want &{new})", f)
}
But i get:
&{old}
&{old}
I tried around with various calls (fooer *= z
, *fooer = *z
, ..) but I cant seem to get it right.
You can try this example at play.golang: http://play.golang.org/p/EZEh3X8yHC
Okay, I think it works like this:
func swap(fooer Fooer) {
foo, _ := fooer.(*Foo)
*foo = *z
}
Like most things in Go, interfaces are simply values. Assigning a new value within a function isn't going to change the value copied into the function arguments.
Because you want to replace the interface value, you need a pointer to the value just like you would any other. It's a very rare case where you could use a pointer to an interface: http://play.golang.org/p/EZEh3X8yHC
func swap(fooer *Fooer) {
z := Fooer(&Foo{foo: "new"})
*fooer = z
}
func main() {
var f Fooer = &Foo{foo: "old"}
fmt.Printf("%s (want &{old})\n", f)
swap(&f)
fmt.Printf("%s (want &{new})", f)
}
But, since a pointer to an interface is almost always a mistake (you can see we have to be very explicit to make this work), you should really have a good reason for implementing something this way, and document it well.
What you most likely want is to extract the pointer from the interface, and assign a new value in there (which is what you added to end of your question). This is a much better construct, but the type must match, so the interface isn't needed.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With