假设我必须实现在两个不同的包中声明的两个不同的接口(在两个不同的独立项目中)。
我有包装 A
A
package A type interface Doer { Do() string } func FuncA(Doer doer) { // Do some logic here using doer.Do() result // The Doer interface that doer should implement, // is the A.Doer }
并包装 B
B
package B type interface Doer { Do() string } function FuncB(Doer doer) { // some logic using doer.Do() result // The Doer interface that doer should implement, // is the B.Doer }
在我的main包里
main
package main import ( "path/to/A" "path/to/B" ) type C int // this method implement both A.Doer and B.Doer but // the implementation of Do here is the one required by A ! func (c C) Do() string { return "C now Imppement both A and B" } func main() { c := C(0) A.FuncA(c) B.FuncB(c) // the logic implemented by C.Do method will causes a bug here ! }
如何处理这种情况?
正如常见问题解答所提到的
其他语言的经验告诉我们,使用具有相同名称但签名不同的多种方法有时会很有用,但在实践中也可能会造成混淆和脆弱。 在Go的类型系统中,仅按名称进行匹配并要求类型一致是简化的主要决定 。
在您的情况下,您将满足两个接口。
您可以通过执行以下操作来测试对象(接口类型)是否满足另一种接口类型A.Doer:
A.Doer
if _, ok := obj.(A.Doer); ok { }
OP添加:
但是,用这种Do方法实现的逻辑与中的A完全不同B。
Do
然后,您需要围绕对象实现包装器:
DoerA
C
A.Do()
DoerB
B.Do()
这样,您将知道将哪个Doer传递给期望an A.Doer或a 的函数B.Doer。 您将不必Do()在原始对象上实现一个方法C,该方法将无法应对A.Do()and 的不同逻辑B.Do()。
B.Doer
Do()