如何避免需要指针接收器的接口方法实现?

huangapple go评论86阅读模式
英文:

How to avoid interface method implementations that needs a pointer receiver?

问题

考虑以下示例: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++ // 没有错误,但现在我们在具有c副本的上下文中递增c.x
}

如何使原始实现在c = &Counter{}上不需要&?换句话说,如何完全避免在C.Increment实现中需要指针接收器?

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

英文:

Consider the following example: 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)	
}

Unfortunatelly I need to c = &Counter{} because Counter.Increment() implementation has a pointer receiver otherwise c.Increment() calls won't be able to modify c.x property:

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

How to make original implementation works without & on c = &Counter{}? In other words, how to avoid the need for the pointer receiver on C.Increment implementation at all?

This is just a nit, but I think that maybe a pointer is not necessary to do that in Go.

答案1

得分: 4

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

考虑到Go通常通过传递一切,使用指针接收器是实现你想要的自然方式。
这在Go FAQ中得到了支持:

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

你可以在"Things I Wish Someone Had Told Me About Golang: pointers"中找到类似的结论。

英文:

> This is just a nit, but I think that maybe a pointer is not necessary to do that in Go.

Considering that Go uses to pass everything by value, a pointer receiver is the natural way to achieve what you want.
This is supported by the Go FAQ:

> First, and most important, does the method need to modify the receiver? If it does, the receiver must be a pointer.

You would find a similar conclusion in "Things I Wish Someone Had Told Me About Golang: pointers"

答案2

得分: 2

你可以考虑定义一个NewCounter函数,该函数封装了你的类型(或第三方类型)的初始化,并返回一个*Counter。使用方法可能如下所示:

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

You could consider defining an NewCounter function that encapsulates the initialization of your type (or some 3rd party) and returns a *Counter. Usage could look something like this:

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

huangapple
  • 本文由 发表于 2014年12月7日 17:36:06
  • 转载请务必保留本文链接:https://go.coder-hub.com/27341367.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定