作者:UP7家族--婵婵_172 | 来源:互联网 | 2023-05-25 11:31
假设我必须实现在两个不同的包中声明的两个不同的接口(在两个不同的分离项目中).
我有包裹 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
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
包裹中
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 !
}
如何应对这种情况?
1> VonC..:
正如常见问题提到的那样
使用其他语言的经验告诉我们,使用具有相同名称但签名不同的各种方法偶尔会有用,但在实践中它也可能令人困惑和脆弱.
仅根据名称进行匹配并要求在类型中保持一致性是Go类型系统中的主要简化决策.
在您的情况下,您将满足两个接口.
您可以通过执行以下操作来测试对象(接口类型)是否满足另一种接口类型A.Doer
:
if _, ok := obj.(A.Doer); ok {
}
OP增加:
但是Do
要满足的方法中实现的逻辑与中的A
完全不同B
.
然后你需要在你的对象周围实现一个包装器:
a DoerA
,将您的对象C
作为字段,并A.Do()
以满足A.Do()
应该如何工作的方式实现
a DoerB
,具有与C
字段相同的对象,并B.Do()
以满足B.Do()
应该如何工作的方式实现
这样,您将知道哪个Doer传递给期望a A.Doer
或a 的函数B.Doer
.
你不会实现Do()
你的原始对象上的方法C
,这将是无法应付的不同的逻辑A.Do()
和B.Do()
.