为了账号安全,请及时绑定邮箱和手机立即绑定

如何使用相同的方法签名实现两个不同的接口

如何使用相同的方法签名实现两个不同的接口

Go
LEATH 2021-09-13 10:35:39
假设我必须实现在两个不同的包中声明的两个不同的接口(在两个不同的独立项目中)。我在包裹里 Apackage Atype 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}并在包 Bpackage Btype 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 mainimport (    "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 !}如何处理这种情况?
查看完整描述

2 回答

?
慕妹3146593

TA贡献1820条经验 获得超9个赞

正如常见问题中提到的

使用其他语言的经验告诉我们,拥有多种名称相同但签名不同的方法有时很有用,但在实践中也可能会令人困惑和脆弱。
仅按名称匹配并要求类型一致是 Go 类型系统中的一个主要简化决策

在您的情况下,您会满足两个接口。

您可以通过执行以下操作来测试对象(接口类型)是否满足另一种接口类型A.Doer

if _, ok := obj.(A.Doer); ok {
}

OP补充说:

但是Do方法中实现的逻辑来满足AB.

然后你需要在你的对象周围实现一个包装器:

  • DoerA,它将您的对象C作为一个字段,并A.Do()以满足A.Do()应该如何工作的方式实现

  • DoerB,它具有与C字段相同的对象,并B.Do()以满足B.Do()应该如何工作的方式实现

这样,您将知道将哪个 Doer 传递给期望 anA.Doer或 a的函数B.Doer
您不必Do()在原始 object 上实现一个方法C,这将无法处理A.Do()and的不同逻辑B.Do()


查看完整回答
反对 回复 2021-09-13
?
一只甜甜圈

TA贡献1836条经验 获得超5个赞

根据定义,您同时满足以下两点

Go 类型通过实现该接口的方法来满足该接口,仅此而已。此属性允许在无需修改现有代码的情况下定义和使用接口。它支持一种促进关注点分离和改进代码重用的结构类型,并使构建随着代码开发而出现的模式变得更加容易。接口的语义是 Go 具有敏捷、轻量级感觉的主要原因之一。

因此,考虑到这一点,您可以:

a) 向定义您对逻辑的期望的接口方法添加注释(请参阅 io.Reader 接口或一个很好的示例)

b) 在接口上添加一个名为ImplementsDoerA 和ImplementsDoerB 的额外方法(也在FAQ 中提到)。


查看完整回答
反对 回复 2021-09-13
  • 2 回答
  • 0 关注
  • 238 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信