【问题标题】:Replace value of interface替换接口的值
【发布时间】:2016-01-15 18:09:46
【问题描述】:

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

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
}

【问题讨论】:

  • 您的编辑可能更像您想要的,但是界面没有意义,因为您只能分配完全相同的类型。
  • 是的,绝对正确:D

标签: pointers go


【解决方案1】:

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

但是,由于指向接口的指针几乎总是错误的(你可以看到我们必须非常明确地完成这项工作),你应该真的有充分的理由来实现这样的东西方式,并做好记录。

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

【讨论】:

  • 好吧,再问一个问题,json.Encode(interface{})gob.Encode(interface{}) 使用接口作为参数但仍然能够以某种方式写入值是如何工作的
  • @machete:那些使用反射和类型断言,你必须传入一个要分配的指针。您仍然无法更改接口的动态类型,即如果您传入*string,则无法将其替换为*int。通过反射实现的类似功能:play.golang.org/p/u_lBBPeRfz
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-10-18
  • 1970-01-01
  • 1970-01-01
  • 2019-10-29
  • 2019-08-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多