为了账号安全,请及时绑定邮箱和手机立即绑定

带有指针接收器的 Golang 方法

带有指针接收器的 Golang 方法

Go
郎朗坤 2021-11-22 19:36:39
我有这个示例代码package mainimport (    "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) 中看到了这个问题,如何将接口指针转换为结构指针?,但我看不出它与这个例子有什么关系。
查看完整描述

2 回答

?
慕侠2389804

TA贡献1719条经验 获得超6个赞

您指向结构的指针应该实现接口。通过这种方式,您可以修改其字段。


看看我是如何修改你的代码的,让它按你的预期工作:


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() *Implementation {

    return &Implementation{someField: "Hello"}

}


func main() {

    var a IFace

    a = Create()

    a.SetSomeField("World")

    fmt.Println(a.GetSomeField())

}


查看完整回答
反对 回复 2021-11-22
?
天涯尽头无女友

TA贡献1831条经验 获得超9个赞

简单的答案是,您将无法在以SetSomeField您想要的方式工作的同时让结构实现您的接口。

但是,指向结构的指针将实现接口,因此更改您的Create方法 doreturn &obj应该可以使事情正常工作。

潜在的问题是您修改后的SetSomeField方法不再在Implementation. 虽然该类型*Implementation将继承非指针接收器方法,但反之则不然。

其原因与指定接口变量的方式有关:访问存储在接口变量中的动态值的唯一方法是复制它。例如,想象以下内容:

var impl Implementation
var iface IFace = &impl

在这种情况下,调用可以iface.SetSomeField工作,因为它可以复制指针以用作方法调用中的接收者。如果我们直接在接口变量中存储一个结构体,我们需要创建一个指向该结构体的指针来完成方法调用。一旦创建了这样的指针,就可以访问(并可能修改)接口变量的动态值而无需复制它。


查看完整回答
反对 回复 2021-11-22
  • 2 回答
  • 0 关注
  • 235 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信