Golang类型断言/强制转换为中间结构

时间:2018-03-26 02:50:50

标签: go go-interface

考虑以下类型:

type Event interface{}

type ActionResultEvent struct {
    Result string
}

type ActionSuccessEvent ActionResultEvent
type ActionFailureEvent ActionResultEvent

type eventHandleFunc func(e Event)

我的目标是为具体类型eventHandleFuncActionSuccessEvent以及更抽象的ActionFailureEvent提供事件处理程序(类型为ActionResultEvent)。后者我想用于ActionSuccessEventActionFailureEvent s。

现在我的想法是只将Event接口输入到我想要处理的结构中,并且适用于具体类型。

// Working perfectly fine
func(e Event) {
  event := e.(ActionFailureEvent)
  fmt.Println(event.Result)
} (ActionFailureEvent{ Result: "failure" })

func(e Event) {
  event := e.(ActionSuccessEvent)
  fmt.Println(event.Result)
} (ActionSuccessEvent{ Result: "success" }) 

现在接受ActionResultEvent的处理程序呢?我最喜欢的看起来像这样:

func(e Event) {
  event := e.(ActionResultEvent)
  fmt.Println(event.Result)
} (ActionSuccessEvent{ Result: "success" })    

这显然是恐慌,因为e的类型为ActionSuccessEvent

然后我们当然可以转换为初始类型并返回到中间类型:

// Works but would that would need to change whenever new types "extending" 
// ActionResultEvent are added
func(e Event) {
  var resultEvent ActionResultEvent

  switch e.(type) {
  case ActionSuccessEvent:
    resultEvent = ActionResultEvent(e.(ActionSuccessEvent))

  case ActionFailureEvent:
    resultEvent = ActionResultEvent(e.(ActionFailureEvent))
  }
  fmt.Println(resultEvent.Result)
} (ActionSuccessEvent{ Result: "success" })

从我的角度来看,另一个非常好的方法是:

// Error: use of e.(type) outside type switch
func(e Event) {
  resultEvent := ActionResultEvent(e.(type))
} (ActionSuccessEvent{ Result: "success" })

有人能想到一个顺利的解决方案吗?一方面注意:如果在运行时遇到类型转换失败时处理程序发生混乱,我很高兴,因为包装器将从中恢复。

这是playground上面的示例代码。谢谢!

1 个答案:

答案 0 :(得分:0)

虽然我在这里投票,但我相信其他人可能会感兴趣。所以我决定将解决方案发布到我已经想到的工作中:参见playground

如果这是不好的做法,或者不是做事的“走路”,我会很乐意得到一些反馈。谢谢!