Или внутри условия
У меня есть этот код:
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
}
и так далее.