次のタイプがあるとします。
type Event interface{}
type ActionResultEvent struct {
Result string
}
type ActionSuccessEvent ActionResultEvent
type ActionFailureEvent ActionResultEvent
type eventHandleFunc func(e Event)
eventHandleFunc
私の目標は、具体的なタイプActionSuccessEvent
、ActionFailureEvent
、およびより抽象的な のイベントハンドラー (タイプ ) を持つこと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" })
誰でもスムーズな解決策を思いつくことができますか? 補足: 実行時に型キャストが失敗するたびにハンドラーがパニックに陥った場合、ラッパーがそれから回復するので、私は満足しています。
これは、上記のプレイグラウンドのコード例です。ありがとう!