在golang中,如果其中一个方法必须有指针接收器,是否有必要更改类型的所有方法?

时间:2018-04-20 08:52:17

标签: go interface

我正在研究golang,我对定义值或指针的方法感到有些困惑。如doc中所述:

  

接下来是一致性。如果该类型的某些方法必须具有   指针接收器,其余的也应该是,所以方法集是   无论使用何种类型,都是一致的。请参阅有关的部分   方法设置细节。

如果我有类型T,则需要实现多个接口。一个接口具有需要使用指针接收器的方法,并且另一个接口中的方法可以与值接收器很好地协作。是否有必要更改所有接口中的所有方法以使用指针接收器?如果是这样,为什么?

3 个答案:

答案 0 :(得分:2)

取决于:)

您的类型T有两个方法集:

  • 接收器(t T)的方法集,它是所有定义的方法 接收者(t T)

  • 接收器的方法集(t * T),它是所有具有接收器的方法(t * T) AND 所有具有接收器的方法(t T)

因此,如果您有一个T满足的接口,那么* T也会满足。 (但反之亦然)

因此,如果您必须将* T接收器方法添加到某个类型以满足接口,则不需要 将其他方法接收器更改为* T,但您必须注意现在只有* T满足该接口而不是T和其他接口可能都满足。

type fooer interface {
    foo()
}

type barer interface {
    bar()
}

type T struct {}

func (t T)foo(){}

func (t *T)bar(){}

var _ fooer = T{}  // ok
var _ barer = T{}  // NOT OK - won't compile
var _ barer = &T{} // ok
var _ fooer = &T{} // ok

混淆?是的,它可以。因此,尽管你没有 来改变所有方法以获得指针接收器,但是如果你这样做的话,它会更加一致并且不那么令人困惑 - 这样你知道你总是在处理一个* T代码 - 似乎是大多数人所做的。

答案 1 :(得分:1)

不需要。你引用的只是这个的论据。因此建议使用。

答案 2 :(得分:0)

正如你所提到的关于Golang规范的方法有指针或值接收器。 If an interface as a method receiver then its better for consistency to have other methods with pointer receivers。但这没有必要。

让我们需要指针接收器。假设我有一个结构,其中包含数据库连接和会话的详细信息。并且存在使用插入/更新/删除查询的方法使用相同连接的方法。然后最好指针接收器,这样你不需要每次都创建连接。您可以使用当前会话管理用于查询数据库的所有方法。

type Env struct {
    db *sql.DB
}

func main() {
    db, err := models.NewDB("postgres://user:pass@localhost/dbname")
    if err != nil {
        log.Panic(err)
    }
    env := &Env{db: db}
}


func (env *Env) fetch(){}
func (env *Env) Insert(){}
func (env *Env) Update(){}