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

时间:2018-01-05 04:22:42

标签: go

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

有更好的方法吗?

1 个答案:

答案 0 :(得分:1)

将类型作为指针声明为另一种类型几乎不是您想要的,因为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()
}