Я строю отображение CST на AST для antlr, поэтому у меня есть тонны *Context
классов, которые мне нужно сопоставить с соответствующими им узлами AST.У меня есть классы, созданные ANTLR, и мои методы отображения:
// Demo data:
open class Super
class Sub0: Super
class Sub1: Super
// Mappers:
fun map(a: Super) = println("Super")
fun map(a: Sub0) = println("Sub0")
fun map(a: Sub1) = println("Sub1")
Затем я хотел бы использовать его следующим образом:
listOf(Super(), Sub0(), Sub1()).forEach {
when (it) {
is B, is C -> { print('*'); map(it) }
else -> map(it)
}
}
Я бы ожидал, что it
будетсмарт-приведение к Sub0 или Sub1 и вызов правильного map
, который, однако, дает:
Super
*Super
*Super
, который указывает, что он выбрал правильный путь, но не выполнил автоматическое приведение.Этот подход работает, но он действительно длится, так как у вас все больше и больше SubX
:
when (it) {
is Sub0 -> {
print("*");
map(it)
}
is Sub1 -> {
print("*");
map(it)
}
else -> map(it)
}
Я знаю, что могу использовать некоторую черную магию в форме отражения и перебирать все map(X)
s изатем используйте какой-нибудь «умный трюк», чтобы выбрать правильный, но я бы предпочел этого не делать.;)