V8025. The case in a type switch is unreachable. A previous case already covers this type.
Анализатор обнаружил case-клаузу в конструкции type switch, которая никогда не будет выполнена. Тип, ожидаемый указанной case-клаузой, уже был перехвачен одной из предыдущих case-клауз.
Рассмотрим пример:
type Value interface {
GetValue() string
}
type ConcreteValue struct {
value string
}
func (v *ConcreteValue) GetValue() string {
return v.value
}
....
func foo(x any) {
switch x.(type) {
case Value:
....
case *ConcreteValue: // <=
....
}
}
В первой case-клаузе проверяется, реализует ли x интерфейс Value, а во второй — имеет ли x тип *ConcreteValue. Согласно спецификации языка Go, подходящий блок для исполнения определяется в момент обхода списка типов в case-клаузах сверху вниз слева направо. При первом соответствии поток управления будет передан соответствующему блоку. Поскольку тип *ConcreteValue реализует интерфейс Value, то объекты такого типа будут перехвачены первой case-клаузой, а не второй, как задумывал программист.
Чтобы избежать проблем с маскированием типов, следует всегда указывать более специфичные конкретные типы (или указатели на них) выше общих интерфейсов:
func foo(x any) {
switch x.(type) {
case *ConcreteValue:
....
case Value:
....
}
}