drbouzlxb92333332 2018-03-26 02:50
浏览 55

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

Given the following types:

type Event interface{}

type ActionResultEvent struct {
    Result string
}

type ActionSuccessEvent ActionResultEvent
type ActionFailureEvent ActionResultEvent

type eventHandleFunc func(e Event)

My goal is to have event handlers (of type eventHandleFunc) for the concrete types ActionSuccessEvent, ActionFailureEvent, as well as for the more abstract ActionResultEvent. The latter I would like to use for both ActionSuccessEvents and ActionFailureEvents.

Now my idea was to just type cast the Event interface to the structure I would like to work on and that works nicely for the concrete types.

// 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" }) 

Now what about handlers accepting ActionResultEvents? My absolute favourite would look like this one:

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

This obviously panics as e was of type ActionSuccessEvent.

Then we can of course cast to the initial type and back to intermediate:

// 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" })

Another really nice approach from my point would be:

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

Can anybody think of a smooth solution? One side note: I am happy if the handler panics during runtime whenever a typecast fails, as the wrapper will recover from that.

This is the example code above on the playground. Thanks!

  • 写回答

1条回答 默认 最新

  • dongtang6775 2018-03-26 06:04
    关注

    Although I got down votes here, I believe this could be of interest to others. So I decided to post the solution to what I have figured out to work: See the playground

    If this is bad practice or not "the go way" of doing things I would be really happy to get some feedback. Thanks!

    评论

报告相同问题?

悬赏问题

  • ¥15 想问一下树莓派接上显示屏后出现如图所示画面,是什么问题导致的
  • ¥100 嵌入式系统基于PIC16F882和热敏电阻的数字温度计
  • ¥15 cmd cl 0x000007b
  • ¥20 BAPI_PR_CHANGE how to add account assignment information for service line
  • ¥500 火焰左右视图、视差(基于双目相机)
  • ¥100 set_link_state
  • ¥15 虚幻5 UE美术毛发渲染
  • ¥15 CVRP 图论 物流运输优化
  • ¥15 Tableau online 嵌入ppt失败
  • ¥100 支付宝网页转账系统不识别账号