我正在研究golang,我对定义值或指针的方法感到有些困惑。如doc中所述:
接下来是一致性。如果该类型的某些方法必须具有 指针接收器,其余的也应该是,所以方法集是 无论使用何种类型,都是一致的。请参阅有关的部分 方法设置细节。
如果我有类型T,则需要实现多个接口。一个接口具有需要使用指针接收器的方法,并且另一个接口中的方法可以与值接收器很好地协作。是否有必要更改所有接口中的所有方法以使用指针接收器?如果是这样,为什么?
答案 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(){}