替换接口值

问题描述 投票:0回答:2

我想像这样替换接口的值:

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)
}

但我明白:

&{old}
&{old}

我尝试了各种调用(

fooer *= z
*fooer = *z
,..),但我似乎无法正确。

您可以在 play.golang 尝试此示例:http://play.golang.org/p/EZEh3X8yHC


好吧,我想它是这样工作的:

func swap(fooer Fooer) {
    foo, _ := fooer.(*Foo)
    *foo = *z
}
pointers go
2个回答
11
投票

像 Go 中的大多数东西一样,接口只是值。在函数中分配新值不会更改复制到函数参数中的值。

因为您想要替换接口值,所以您需要一个指向该值的指针,就像任何其他值一样。在极少数情况下,您可以使用指向接口的指针: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)
}

但是,由于指向接口的指针几乎总是一个错误(您可以看到我们必须非常明确才能使其工作),因此您应该真的有充分的理由以这种方式实现某些东西,并很好地记录它。

您最可能想要的是从接口中提取指针,并在其中分配一个新值(这是您在问题末尾添加的内容)。这是一个更好的构造,但类型必须匹配,因此不需要接口。


0
投票

我觉得这样更好。您分配“新”字符串来替换 Foo 实例中的“旧”字符串。

...

func swap(fooer Fooer) {
    fooer.Foo(z.foo)
}

func main() {
    f := Foo{foo: "old"}
    fmt.Printf("%s (want &{old})", f)
    fmt.Println("")

    swap(&f)
    fmt.Printf("%s (want &{new})", f)

}
© www.soinside.com 2019 - 2024. All rights reserved.