Interface 如何使用相同的方法签名实现两个不同的接口
假设我必须实现在两个不同包中声明的两个不同接口(在两个不同的独立项目中) 我的包裹里有Interface 如何使用相同的方法签名实现两个不同的接口,interface,go,Interface,Go,假设我必须实现在两个不同包中声明的两个不同接口(在两个不同的独立项目中) 我的包裹里有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
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 !
}
如何处理这种情况?作为
使用其他语言的经验告诉我们,使用各种名称相同但签名不同的方法有时是有用的,但在实践中也可能令人困惑和脆弱。在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()
a.Doer
或B.Doer
您不必在原始对象
C
上实现Do()
方法,这将无法处理a.Do()
和B.Do()
的不同逻辑 根据定义,
Go类型通过实现接口的方法来满足接口,仅此而已。此属性允许定义和使用接口,而无需修改现有代码。它支持一种结构化类型,这种类型可以促进关注点的分离并改进代码的重用,并且更容易基于代码开发时出现的模式进行构建。界面的语义是Go灵活、轻量级感觉的主要原因之一
因此,考虑到这一点,您可以:
a) 在接口方法中添加注释,定义您对逻辑的期望(请参阅io.Reader接口或一个好的示例)
b) 在接口上添加一个名为ImplementsDoerA和ImplementsDoerB的额外方法(也在常见问题解答中提到)。完全没有什么需要处理的:任何类型都有一个方法
Do()字符串
实现两个接口a.Doer
和b.Doer
。我认为你是对的@Volker,没有解决办法,这种情况可能发生在任何使用接口的语言中(java
),但是Do
方法中实现的满足A
的逻辑与B
中的逻辑完全不同。谢谢@VonC,我也是,我添加了更多的代码来澄清这个问题。