Kotlin: умный актерский состав с несколькими типами - PullRequest
2 голосов
/ 15 апреля 2019

Я строю отображение 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 изатем используйте какой-нибудь «умный трюк», чтобы выбрать правильный, но я бы предпочел этого не делать.;)

1 Ответ

4 голосов
/ 15 апреля 2019

Интеллектуальное приведение не работает, потому что код внутри ветви when is B, is C -> map(it) проверяется только один раз.Он не скомпилирован для двух разных наборов инструкций для одного типа и другого.Компилятору нужно определить один тип для it, который будет работать в обоих случаях.

Ни один из Sub0 и Sub1 не может быть выбран для типа it, поскольку выбирается один из нихне распространяется на других.Таким образом, компилятор выбирает наименее распространенный супертип из Sub0 и Sub1, который равен Super.Затем вызов map разрешается со статически известным типом Super для it.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...