Go:接口中的可选方法

J.D*_*Doe 2 oop object go

我正在开发一个严重依赖基本代码库的项目.在基本代码中,有一个名为eventWatcher的接口(在此简化)

//Baselibrary.go:
     package base
     type eventHandle interface {
         eventHookTypeA
         eventHookTypeB
         someOtherMethod() results
     }
     type eventHookTypeA interface {
         // method definitions
         HandleEventA() results
     }
     type eventHookTypeB interface {
         // method definitions
         HandleEventB() results
     }

     func handleEvents(eventType string, handle eventHandle) results {
          if eventType == "eventA" {
             return handle.HandleEventA()
          } else if eventType == "eventB" {
             return handle.HandleEventB()
          }
          return nil
     }
Run Code Online (Sandbox Code Playgroud)

对于我们的项目,我们现在有第三种事件类型(例如eventTypeC),它是我们项目独有的.一种方法是在基类中添加第三个接口定义(eventHookTypeC),并在我们自己的项目代码中相应地实现.然而,我们的CI环境也将采用这个新版本的Baselibrary.go并使用它构建所有其他项目,这将失败,因为它们将缺少eventHookTypeC的impl.

除了更改我们的构建环境或repo之外,是否有一个Go解决方法,而无需更改其他项目的代码?

Adr*_*ian 8

你可以像使用eg http.Pusher或者那样完成它io.Closer.使用"可选"方法创建新接口,并传递原始接口.当您想要执行可选方法时,可以使用类型断言来检查您所拥有的值是否实现了另一个接口,如果是,则调用该方法.

 type eventHandle interface {
     eventHookTypeA
     eventHookTypeB
     // DON'T add TypeC interface.
     someOtherMethod() results
 }
 type eventHookTypeA interface {
     // method definitions
     HandleEventA() results
 }
 type eventHookTypeB interface {
     // method definitions
     HandleEventB() results
 }
 type eventHookTypeC interface {
     HandleEventC() results
 }

 func handleEvents(eventType string, handle eventHandle) results {
      if eventType == "eventA" {
         return handle.HandleEventA()
      } else if eventType == "eventB" {
         return handle.HandleEventB()
      } else if eventType == "eventC" {
         if c,ok := handle.(eventHookTypeC); ok {
             return c.HandleEventC()
         } else {
             log.Println("somewhat bad happen")
         }
      }
      return nil
 }
Run Code Online (Sandbox Code Playgroud)