有效地将公共 sdk 类型包装在 golang 中



我正在使用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()
}

最新更新