如何用相同的方法签名实现两个不同的接口 [英] How to implement two different interfaces with the same method signature
问题描述
我在包 A
包A
类型接口Doer {
do()字符串
}
func FuncA(Doer doer){
//使用doer.Do()执行一些逻辑结果
// Doer应该实现的Doer接口,
//是A.Doer
}
并且在包中 B
包B
类型接口Doer {
Do()字符串
}
函数FuncB(Doer doer){
//使用doer.Do的某些逻辑()result
// doer应该实现的Doer接口,
//是B.Doer
}
在我的主要
包中
package main
import(
path / to / A
path / to / B
)
类型C int
//这个方法实现A.Doer和B.Doer,但是
//这里执行Do是所需的一个 !
func(c C)Do()string {
returnC now imppement both A and B
}
func main(){
c := C(0)
A.FuncA(c)
B.FuncB(c)//由C.Do方法实现的逻辑会导致一个错误!
}
如何处理这种情况?
正如常见问题解答
其他语言的使用经验告诉我们,使用名称相同但签名不同的多种方法偶尔有用,但也可能会造成混淆并且在实践中很脆弱。
仅通过名称进行匹配并要求类型一致性是Go类型系统中的一个主要简化决策。
在您的情况下,您可以同时满足这两个界面。
您可以你可以通过这样做来测试一个对象(接口类型)是否满足另一个接口类型 A.Doer
if _,ok:= obj。(A.Doer); OK {
}
:
但是在
Do
方法中实现的逻辑满足A
与B
中的完全不同。
然后你需要在你周围实现一个包装对象:
DoerA
,它的对象是 C
作为一个字段,并且以一种方式实现 A.Do()
满足如何 A.Do()
应该工作
DoerB
,它的同一个对象 C
作为一个字段,并且以满足如下的方式实现 B.Do()
B.Do()
应该工作
这样,知道哪个Doer传递给函数,期望 A.Doer
或者 B.Doer
。
您不必在原始对象 C
上实现 Do()
方法, ld无法应付 A.Do()
和 B.Do()
的不同逻辑。
Suppose that I have to implement two different interfaces declared in two different packages (in two different separated projects).
I have in the package 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
}
And in package 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
}
In my main
package
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 !
}
How to deal with this situation ?
As the FAQ mentions
Experience with other languages told us that having a variety of methods with the same name but different signatures was occasionally useful but that it could also be confusing and fragile in practice.
Matching only by name and requiring consistency in the types was a major simplifying decision in Go's type system.
In your case, you would satisfy both interfaces.
You can you the can test whether an object (of an interface type) satisfies another interface type A.Doer
, by doing:
if _, ok := obj.(A.Doer); ok {
}
The OP adds:
But the logic implemented in the
Do
method to satisfyA
is completely different from the one inB
.
Then you need to implement a wrapper around you object:
- a
DoerA
, which has your objectC
as a field, and implementA.Do()
in a manner that satisfy howA.Do()
is supposed to work - a
DoerB
, which has your same objectC
as a field, and implementB.Do()
in a manner that satisfy howB.Do()
is supposed to work
That way, you will know which Doer to pass to a function expecting an A.Doer
or a B.Doer
.
You won't have to implement a Do()
method on your original object C
, which would be unable to cope with the different logic of A.Do()
and B.Do()
.
这篇关于如何用相同的方法签名实现两个不同的接口的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!