英文:
Golang package interface
问题
我对golang还不太熟悉,关于包和接口方面我有一个问题。
如果我有一个需要使用接口实现的package1,并且将来可能需要用其他实现来替换,这种情况是否可行?
以下是伪代码示例:
implementation包包含接口的当前实现
type TestI interface {
M1()
}
package implementation
type Impl struct {}
func (i *Impl) M1() {
// 做一些操作
}
package package1
import "path/to/TestI" // 以某种方式导入TestI,并调用M1方法,但可以灵活地将其与接口的其他实现交换
package1应该在不知道具体实现的情况下使用接口(类似于C#或Java中的依赖注入,package1只需知道接口,而不需要知道具体实现)。
TestI接口应该在哪里定义?如果有点混乱,我很抱歉,我只是试图理清思路。
这在C#中的等效代码如下:
interface ITest {
void SetClass(Class1 cl);
}
// package1
class Class1 {
private ITest test;
public void SomeMethod() {
// 我希望以某种方式在其他包中设置这个
test.SetClass(this);
}
}
// package2
class Test : ITest {
private Class1 c1;
public void SetClass(Class1 c) {
this.c1 = c;
}
}
英文:
I am bit new to golang and I have a question about packages and interfaces.
If I have package1, that needs to use implementation of an interface that can be swapped in future with other implementation, would that be possible?
some pseudo code
package implementation contains current implementation of interface
type TestI interface {
M1()
}
package implementation
type Impl struct {}
funct (i *Impl) M1 ( ... do something )
package package1
import TestI somehow and call M1 method but with flexibility to swap it with other implementation of this interface in future?
package package1 should use implementation without knowing about it (something like DI in c# or java, package should only know about interface, and not about implementation)
Where should TestI interface be defined? Sorry if this is a bit confusing, just trying to get my head around it.
This is equivalent in c#
ITest {
SetClass(Class1 cl);
}
// package1
class Class1 {
private ITest test {get; set;}
public void SomeMethod() {
// i want to somehow set this in other package
test.SetClass(this);
}
}
// package2
class Test implements ITest {
private Class1 cl;
SetClass(Class1 c) {
this.c1 = c;
}
}
答案1
得分: 1
除非您正在编写一个以接口为先的应用程序,否则通常最好在不声明任何接口的情况下编写具体实现。然后,该包的用户可以声明所需的接口。例如:
type Implementation struct {
...
}
func (i Implementation) FuncA() {...}
func (i Implementation) FuncB() {...}
如果需要实现FuncA
的某种类型,您可以声明:
type IntfA interface {
FuncA()
}
任何具有方法FuncA
的类型都实现了IntfA
,而Implementation
符合该描述,因此您可以将Implementation
的实例传递给需要IntfA
的函数。
类似地,如果您需要一个既有FuncA
又有FuncB
的接口,您可以声明:
type IntfAB interface {
FuncA()
FuncB()
}
Implementation
也实现了IntfAB
。
因此,理想情况下,您应该在使用接口的地方声明所需的接口,任何具有匹配方法集的类型都可以用于实现该接口。
如果您是基于现有接口编写代码,那么您可以将该接口放在与实现不同的包中,或者您可以将接口和实现放在同一个包中,具体取决于您的用例。
英文:
Unless you are writing an interface-first application, it is generally best to write the concrete implementations without declaring any interfaces. Then the users of that package can declare the necessary interfaces. For example:
type Implementation struct {
...
}
func (i Implementation) FuncA() {...}
func (i Implementation) FuncB() {...}
If some type that implements FuncA
is required, you can declare:
type IntfA interface {
FuncA()
}
Any type that has the method FuncA
implements IntfA
, and Implementation
fits that description, so you can pass an instance of Implementation
to a function that needs IntfA
.
Similarly, if you need an interface that has both FuncA
and FuncB
, you can declaret:
type IntfAB interface {
FuncA()
FuncB()
}
and Implementation
also implements IntfAB
.
So, ideally, you would declare the interface you need where you use it, and any type with a matching set of methods can be used for the implementation of that interface.
If you are writing based on an existing interface, then you can put that interface in a separate package than the implementation, or you can keep the interface and the implementation in the same package, whichever makes more sense for your use case.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论