Предполагаемый тип - String, но ничего не ожидалось - PullRequest
0 голосов
/ 11 января 2019

Приведенный ниже код не компилируется со следующей ошибкой:

Error:(28, 61) Type mismatch: inferred type is String but Nothing was expected

Мне непонятно, почему это так. Я пытаюсь добиться, чтобы filterMap взял любой фильтр и применил его к входящим данным. Как видно из массива, использованного для проверки: arrayListOf("Message1", 1, 'C'). Есть ли способ добиться этого? Я могу исправить это, указав MutableMap<Filter<Any>, String>, но тогда это означает, что мои фильтры также должны иметь тип (Any) -> Boolean

class Filter<Q> (val predicate: (Q) -> Boolean, val isEnabled: Boolean) {

        constructor(predicate: (Q) -> Boolean) : this(predicate, false)

        override fun equals(other: Any?): Boolean {
            if (other == null || other !is Filter<*>) {
                return false
            }
            return isEnabled == other.isEnabled && predicate == other.predicate
        }

        override fun hashCode(): Int {
            return 0x31 xor predicate.hashCode() xor isEnabled.hashCode()
        }
}

val filterMap: MutableMap<Filter<*>, String> = HashMap()

fun main(args: Array<String>) {
    val messages = arrayListOf("Message1", 1, 'C')
    val isMessage1: (String) -> Boolean  = { it == "Message1" }
    val isMessage1Filter = Filter(isMessage1)


    filterMap.put(isMessage1Filter, "Matched Message1")

    messages.forEach { message ->
        filterMap.filterKeys { it.isEnabled || (it.predicate(message)) }
                .forEach {
                    it.value.forEach {
                        println(it)
                    }
          }
     }
}

1 Ответ

0 голосов
/ 11 января 2019

Фильтр определяется звездной проекцией: Filter<*>, что приводит к функции (Nothing) -> Boolean, когда вы берете функции с карты:

val pred = it.predicate //inferred type: (Nothing) -> Boolean 

Вот почему компилятор не принимает String в качестве аргумента.

Кроме того, ваши messages имеют тип ArrayList<Any>, вы не можете просто использовать их как String.

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

Чтобы это исправить, вы можете изменить все на String generics:

val filterMap: MutableMap<Filter<String>, String> = mutableMapOf()
val messages = listOf("Message1") 

Я знаю, это не удовлетворит вас, потому что вы ищете общее решение. Но тогда вам придется найти способ безопасного приведения сущностей, которые вы берете из неопределенных коллекций.

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