我正在使用pagerduty go sdk来做一堆api请求。特别是我正在利用
func NewClient(authToken string) *Client
以创建新的客户端类型。我想在我自己的工作中添加一些实用程序函数以*Client
。我尝试这样做:
type BetterPdClient *pagerduty.Client
func NewClient(auth string) BetterPdClient {
return pagerduty.NewClient(auth)
}
func (b *BetterPdClient) DoSomething() {
b.GetIncident(....)
}
func main() {
pd_client := NewClient("")
fmt.Println(pd_client)
pd_client.DoSomething()
}
但是我收到以下错误:
invalid receiver type *BetterPdClient (BetterPdClient is a pointer type)
我知道DoSomething()
期待指针作为调用方。我能想到的唯一其他方法是将 ptr 作为函数参数发送:
func NewClient(auth string) *pagerduty.Client {
return pagerduty.NewClient(auth)
}
func DoSomething(cl *pagerduty.Client) {
fmt.Println(cl)
}
func main() {
pd_client := NewClient("")
fmt.Println(pd_client)
DoSomething(pd_client)
}
有没有更好的方法?
一个类型声明为指向另一个类型的指针几乎从来都不是你想要的,因为 Go 不允许你向该新类型添加方法,也不允许您向该类型的指针添加方法,因为您自己已经弄清楚了。这个也不编译:
type T struct{}
type P *T
func (P) M() {}
如果要"扩展"类型而不"隐藏"其现有功能,最好的办法是将其嵌入到结构中。
type T struct{
// ...
}
func (T) M() {}
type U struct {
*T
}
func NewU() *U {
return &U{&T{}}
}
func (U) N() {}
func main() {
u := NewU()
u.M()
u.N()
}
我所说的"隐藏现有功能"的意思是,当您根据另一个已经存在的类型定义一个新类型时,您的新类型将无法直接访问现有类型的方法。您所做的只是说您的新类型应该与现有类型具有相同的结构。尽管值得指出的是,此属性使您能够将一种类型转换为另一种类型......
type T struct{
// ...
}
func (T) M() {}
type U T
func NewU() *U {
return &U{}
}
func (U) N() {}
func main() {
u := NewU()
u.M() // compile error
u.N()
// convert *U to *T and then call M
(*T)(u).M()
}