带有指针接收器的 Golang 方法

我有这个示例代码


package main


import (

    "fmt"

)


type IFace interface {

    SetSomeField(newValue string)

    GetSomeField() string

}


type Implementation struct {

    someField string

}


func (i Implementation) GetSomeField() string {

    return i.someField

}


func (i Implementation) SetSomeField(newValue string) {

    i.someField = newValue

}


func Create() IFace {

    obj := Implementation{someField: "Hello"}

    return obj // <= Offending line

}


func main() {

    a := Create()

    a.SetSomeField("World")

    fmt.Println(a.GetSomeField())

}

SetSomeField 不能按预期工作,因为它的接收器不是指针类型。


如果我将方法更改为指针接收器,我希望可以工作,它看起来像这样:


func (i *Implementation) SetSomeField(newValue string) { ...

编译这会导致以下错误:


prog.go:26: cannot use obj (type Implementation) as type IFace in return argument:

Implementation does not implement IFace (GetSomeField method has pointer receiver)

如何在不创建副本的情况下struct实现接口和方法SetSomeField更改实际实例的值?


这是一个可破解的片段:https : //play.golang.org/p/ghW0mk0IuU


我已经在 go (golang) 中看到了这个问题,如何将接口指针转换为结构指针?,但我看不出它与这个例子有什么关系。


郎朗坤
浏览 236回答 2
2回答

慕侠2389804

您指向结构的指针应该实现接口。通过这种方式,您可以修改其字段。看看我是如何修改你的代码的,让它按你的预期工作:package mainimport (&nbsp; &nbsp; "fmt")type IFace interface {&nbsp; &nbsp; SetSomeField(newValue string)&nbsp; &nbsp; GetSomeField() string}type Implementation struct {&nbsp; &nbsp; someField string}&nbsp; &nbsp;&nbsp;func (i *Implementation) GetSomeField() string {&nbsp; &nbsp; return i.someField}func (i *Implementation) SetSomeField(newValue string) {&nbsp; &nbsp; i.someField = newValue}func Create() *Implementation {&nbsp; &nbsp; return &Implementation{someField: "Hello"}}func main() {&nbsp; &nbsp; var a IFace&nbsp; &nbsp; a = Create()&nbsp; &nbsp; a.SetSomeField("World")&nbsp; &nbsp; fmt.Println(a.GetSomeField())}

天涯尽头无女友

简单的答案是,您将无法在以SetSomeField您想要的方式工作的同时让结构实现您的接口。但是,指向结构的指针将实现接口,因此更改您的Create方法 doreturn &obj应该可以使事情正常工作。潜在的问题是您修改后的SetSomeField方法不再在Implementation.&nbsp;虽然该类型*Implementation将继承非指针接收器方法,但反之则不然。其原因与指定接口变量的方式有关:访问存储在接口变量中的动态值的唯一方法是复制它。例如,想象以下内容:var&nbsp;impl&nbsp;Implementation var&nbsp;iface&nbsp;IFace&nbsp;=&nbsp;&impl在这种情况下,调用可以iface.SetSomeField工作,因为它可以复制指针以用作方法调用中的接收者。如果我们直接在接口变量中存储一个结构体,我们需要创建一个指向该结构体的指针来完成方法调用。一旦创建了这样的指针,就可以访问(并可能修改)接口变量的动态值而无需复制它。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go