英文:
Can I subclass and redefine a method in Golang?
问题
我正在使用一个Github客户端,它使我能够更轻松地调用Github API方法。
这个库允许我在初始化时提供自己的*http.Client
:
httpClient := &http.Client{}
githubClient := github.NewClient(httpClient)
这样做很好,但现在我需要做一些其他的事情。我想自定义客户端,以便每个请求(即Do
方法)都会添加一个自定义的头部。
我已经阅读了一些关于嵌入的内容,目前我尝试的是这样的:
package trackerapi
import (
"net/http"
)
type MyClient struct {
*http.Client
}
func (my *MyClient) Do(req *http.Request) (*http.Response, error) {
req.Header.Set("cache-control", "max-stale=3600")
return my.Client.Do(req)
}
但编译器不允许我在默认的客户端位置使用我的自定义MyClient
:
httpClient := &trackerapi.MyClient{}
// 错误:无法将httpClient(类型为*MyClient)作为类型*http.Client使用。
githubClient := github.NewClient(httpClient)
我是一个相对新手的Golang开发者,所以我的问题是:这样做是正确的吗?如果不是,有什么推荐的方法?
英文:
I'm using a Github Client that allows me to call github API methods more easily.
This library allows me to provide my own *http.Client
when I initialize it:
httpClient := &http.Client{}
githubClient := github.NewClient(httpClient)
It works fine but now I need something else. I want to customize the Client so that every request (i.e. the Do
method) gets a custom header added.
I've read a bit about embedding and this is what I've tried so far:
package trackerapi
import(
"net/http"
)
type MyClient struct{
*http.Client
}
func (my *MyClient)Do(req *http.Request) (*http.Response, error){
req.Header.Set("cache-control","max-stale=3600")
return my.Client.Do(req)
}
But the compiler does not let me use my custom MyClient
in place of the default one:
httpClient := &trackerapi.MyClient{}
// ERROR: Cannot use httpClient (type *MyClient) as type
//*http.Client.
githubClient := github.NewClient(httpClient)
I'm a bit of a golang newbie so my question is: Is this the right way to do what I want to and, if not, what's the recommended approach?
答案1
得分: 6
可以在Golang中创建子类吗?
简短回答:不可以。Go语言不是面向对象的,因此没有类,因此无法进行子类化。
更详细的回答:
你对嵌入的理解是正确的,但是你无法将自定义的客户端替换为期望*http.Client
的任何东西。这就是Go接口的用途。但是标准库在这里没有使用接口(对于某些情况,它会使用接口,当有意义时)。
另一个可能的方法(根据具体需求而定)是使用自定义的传输方式,而不是自定义的客户端。这确实使用了接口。你可以使用自定义的RounTripper,添加必要的头信息,并将其分配给*http.Client
结构体。
英文:
> Can I subclass ... in Golang?
Short answer: No. Go is not object oriented, therefore it has no classes, therefore subclassing is categorically an impossibility.
Longer answer:
You're on the right track with embedding, but you won't be able to substitute your custom client for anything that expects an *http.Client
. This is what Go interfaces are for. But the standard library doesn't use an interface here (it does for some things, where it makes sense).
Another possible approach which may, depending on exact needs, work, is to use a custom transport, rather than a custom client. This does use an interface. You may be able to use a custom RoundTripper that adds the necessary headers, and this you can assign to an *http.Client
struct.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论