英文:
Error when trying to inject dependency
问题
我正在尝试重构一些代码,以在我的代码中使用依赖注入来使用Docker客户端库。我创建了一个包含我想要能够模拟的方法的接口。
type DockerClient interface {
Ping(context.Context) (types.Ping, error)
}
func NewDockerUtil() (*DockerUtil, error) {
var dockerClient *DockerClient
var err error
dockerClient, err = client.NewEnvClient() //在二元和一元表达式中报告不兼容的类型。
if err != nil {
return nil, err
}
return &DockerUtil{
Client: dockerClient,
}, nil
}
type DockerUtil struct{
Client *DockerClient
}
但是当我尝试分配它时,我得到了在二元和一元表达式中报告不兼容的类型
。我需要做出什么样的改变?
英文:
I'm trying refactor some code to use dependency injection for the Docker client library I use in my code. I created an interface with the method I want to be able to mock
<!--language: go -->
type DockerClient interface {
Ping(context.Context) (types.Ping, error)
}
func NewDockerUtil() (*DockerUtil, error) {
var dockerClient *DockerClient
var err error
dockerClient, err = client.NewEnvClient() //Reports incompatible types in binary and unary expressions.
if err != nil {
return nil, err
}
return &DockerUtil{
Client: dockerClient,
}, nil
}
type DockerUtil struct{
Client *DockerClient
}
But when I try to assign it I get Reports incompatible types in binary and unary expressions.
What exactly do I need to change?
答案1
得分: -1
让我们从使用interface{}
开始,当你定义接口时不要使用指针定义,可以参考这篇好文章。
type DockerUtil struct{
Client DockerClient
}
而且moby Client 实现了很多方法,你想对某些方法使用interface
。
正确的做法是使用类型断言。可以参考这篇Effective Go - 类型断言 和 规范 - 类型断言。
注意: 我没有在我的机器上测试这段代码,你可以试一下。
func NewDockerUtil() (*DockerUtil, error) {
dockerClient, err := client.NewEnvClient()
if err != nil {
return nil, err
}
return &DockerUtil{
Client: dockerClient.(DockerClient),
}, nil
}
注意:
使用DockerUtil.Client
,你只能调用Ping
方法,因为你的接口DockerClient
只定义了Ping
方法。
如果你想以后调用client.Client
支持的所有方法,你需要进行类型断言:
dockerClient := DockerUtil.Client.(*client.Client)
英文:
Let's start with using interface{}
, when you define interface don't use pointer definition, good read here.
type DockerUtil struct{
Client DockerClient
}
And moby Client implements lot of methods and you would like to do interface
for selective methods.
> Right way to do is via Type assertion. Good read Effective Go - Type assertions and Spec - Type assertion.
Note: try this code, I don't have docker env in my machine to test.
func NewDockerUtil() (*DockerUtil, error) {
dockerClient, err := client.NewEnvClient()
if err != nil {
return nil, err
}
return &DockerUtil{
Client: dockerClient.(DockerClient),
}, nil
}
Note:
Using DockerUtil.Client
, you can call only Ping
method since your interface DockerClient
has definition of Ping
method.
If you would like to call all the methods supported by client.Client
later on then you have to do type assertion-
dockerClient := DockerUtil.Client.(*client.Client)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论