【问题标题】:How to avoid interface method implementations that needs a pointer receiver?如何避免需要指针接收器的接口方法实现?
【发布时间】:2014-12-07 09:36:06
【问题描述】:

考虑以下示例:http://play.golang.org/p/eAot_sVwND

package main

import "fmt"

type Incrementor interface {
    Increment()
}

type Counter struct {
    i int

    Incrementor
}

func (c *Counter) Increment(){
    c.i++
} 

func main() {
    var c Incrementor
    c = &Counter{}
    c.Increment()
    fmt.Println(c)  
}

不幸的是,我需要c = &Counter{},因为Counter.Increment() 实现有一个指针接收器,否则c.Increment() 调用将无法修改c.x 属性:

func (c Counter) Increment(){
    c.i++ // no errors, but now we increment c.x having a copy of c as context
}

如何使原始实现在没有& 的情况下在c = &Counter{} 上工作?换句话说,如何完全避免在C.Increment 实现上需要指针接收器?

这只是一个小问题,但我认为在 Go 中可能不需要指针。

【问题讨论】:

    标签: interface go


    【解决方案1】:

    这只是一个小问题,但我认为在 Go 中可能不需要指针。

    考虑到 Go 使用 传递所有内容,指针接收器是实现您想要的结果的自然方式。
    Go FAQ 支持这一点:

    首先,也是最重要的,方法是否需要修改接收器?如果是这样,接收者必须是一个指针。

    你会在“Things I Wish Someone Had Told Me About Golang: pointers”中找到类似的结论

    【讨论】:

    • 那么有没有办法摆脱&&Counter{}的初始化呢?
    • 这种担忧的动机是我发现在使用 tirhd 派对包时通过引用初始化结构非常不愉快,所以我尽量避免它。在看到编译错误之前,您永远不知道如何初始化事物。
    • @marcioAlmada 我理解,但我不知道在 Go 中避免指针初始化的自然方法,当您有一个修改其内容的方法时。
    【解决方案2】:

    您可以考虑定义一个 NewCounter 函数来封装您的类型(或某些第 3 方)的初始化并返回一个 *Counter。用法可能如下所示:

    func main() {
        c := NewCounter()
        c.Increment()
        fmt.Println(c)  
    }
    

    【讨论】:

    • 很好,我们在 go std 库中到处都能看到这种模式。
    猜你喜欢
    • 1970-01-01
    • 2019-11-23
    • 1970-01-01
    • 2018-02-28
    • 2021-01-23
    • 2017-02-10
    • 2013-12-30
    • 2018-10-15
    • 1970-01-01
    相关资源
    最近更新 更多