Или внутри условия

У меня есть этот код:

if ev, ok := evt.(*ATypeEvent); ok {
   //process ATypeEvent
} else if ev, ok := evt.(*BTypeEvent); ok {
   //process BTypeEvent
} else if ev, ok := evt.(*CTypeEvent); ok {
   //process CTypeEvent
}

Так получилось, что у меня есть еще 3 типа событий, которые все вписываются в один из 3 других - я думаю, что мне нужно ИЛИ.

Но после нескольких попыток я так и не смог понять, как это сделать. Это не работает:

if ev, ok := evt.(*ATypeEvent) || evt.(*XTypeEvent); ok {
   //process ATypeEvent and X
} else if ev, ok := evt.(*BTypeEvent)  || evt.(*YTypeEvent); ok {
   //process BTypeEvent and Y
} else if ev, ok := evt.(*CTypeEvent)  || evt.(*ZTypeEvent); ok {
   //process CTypeEvent and Z
}

ни что-то подобное

if ev, ok := evt.(*ATypeEvent) || ev, ok := evt.(*XTypeEvent); ok {

ни

if ev, ok := (evt.(*ATypeEvent) || evt.(*XTypeEvent ) ); ok {

Как это можно сделать правильно?

2 ответа

Решение

Используйте переключатель типа, как описано в Effective Go, очень рекомендуемом ресурсе для чтения и понимания многих вещей в Go:

switch v := ev.(type) {
case *ATypeEvent, *XTypeEvent:
    // process ATypeEvent and X
case *BTypeEvent, *YTypeEvent:
    // process BTypeEvent and Y
case *CTypeEvent, *ZTypeEvent:
    // process CTypeEvent and Z
default:
    // should never happen
    log.Fatalf("error: unexpected type %T", v)
}

Что касается того, почему ваш подход не сработал, Go's || а также && операторы требуют значения типа bool и привести к единственному значению типа bool так что присваивая ev, ok не будет работать так, как вы хотели, и не будет использовать утверждение типа в качестве логического значения. Без переключения типов вы застряли, делая что-то вроде этого:

if ev, ok := evt.(*ATypeEvent); ok {
    //process ATypeEvent
} else if ev, ok := evt.(*XTypeEvent); ok {
    //process XTypeEvent
} else if ...

Другой вариант - определить метод интерфейса для evt.

func (a *ATypeEvent) Process(...) ... {
  //process ATypeEvent
}

func (x *XTypeEvent) Process(...) ... {
  //process XTypeEvent
}

func (b *BTypeEvent) Process(...) ... {
  //process BTypeEvent
}

и так далее.

Другие вопросы по тегам