Смарт бросил Опцию Arrow-kt

Я пытаюсь выполнить интеллектуальное приведение Option из любой переменной Any, чтобы я мог определить, является ли Option пустым, однако в среде IDE указывается, что Option<*> не удалось выполнить интеллектуальное приведение, поскольку он объявлен в другом модуле.

fun hasEmptyValue(column: Pair<String, Any>): Boolean = when {
    column.second is Option<*> -> column.second.isEmpty()  
    else -> false
}

2 ответа

Решение

Дэвид Роусон показывает, как это исправить, но не объясняет, почему ваш код не работает.

Причина в том, что column.second может в принципе вернуть разные значения для двух вызовов; даже если Pair#second это val, он может иметь собственный метод получения.

Если Pair был в том же модуле, компилятор мог проверить это, но для других модулей это не так.

Следующее заставляет Smartcast работать на меня:

fun hasEmptyValue(column: Pair<String, Any>): Boolean {
    val second = column.second
    return when (second) {
        is Option<*> -> second.isEmpty() //Smart cast to arrow.core.Option<*>
        else -> false
    }
}

Объяснение того, почему интеллектуальное приведение между модулями не разрешено, находится на трекере проблем Jetbrains здесь:

Интеллектуальное приведение допустимо только в том случае, если несколько обращений к одному и тому же свойству гарантированно возвращают одно и то же значение. Если доступ к свойству определен в модуле, отличном от местоположения доступа, модуль, содержащий свойство, может быть перекомпилирован отдельно от модуля, к которому оно получено, что нарушает ключевое требование смарт-преобразования. Поэтому кросс-модульные умные броски не допускаются.

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