-1

次のタイプがあるとします。

type Event interface{}

type ActionResultEvent struct {
    Result string
}

type ActionSuccessEvent ActionResultEvent
type ActionFailureEvent ActionResultEvent

type eventHandleFunc func(e Event)

eventHandleFunc私の目標は、具体的なタイプActionSuccessEventActionFailureEvent、およびより抽象的な のイベントハンドラー (タイプ ) を持つことActionResultEventです。ActionSuccessEvent後者はs とs の両方に使用したいと思いActionFailureEventます。

今、私の考えは、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では、 sを受け取るハンドラーはどうなるでしょうか。私の絶対的なお気に入りは次のようになります。

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

誰でもスムーズな解決策を思いつくことができますか? 補足: 実行時に型キャストが失敗するたびにハンドラーがパニックに陥った場合、ラッパーがそれから回復するので、私は満足しています。

これは、上記のプレイグラウンドのコード例です。ありがとう!

4

1 に答える 1

0

ここで反対票を投じましたが、これは他の人にとって興味深いものになると思います。そこで、うまくいくとわかった解決策を投稿することにしました。

これが悪い習慣であるか、物事を行うための「正しい方法」ではない場合、フィードバックをいただければ幸いです。ありがとう!

于 2018-03-26T06:04:06.370 に答える