Kotlin Т значение не может быть назначено с функцией, которая возвращает любое - PullRequest
0 голосов
/ 28 февраля 2020

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

suspend fun <T> GetContent(call: ApplicationCall) : T {
    var requestContent: T? = null

    try {
        requestContent = call.receive()
    }
    catch (exception: Exception) {
        println(exception)
    }
}

Проблема в том, что call.receive() возвращает any, поэтому я получаю сообщение об ошибке "T? Не является подтипом Any".

Итак, я прочитал о Any, и концепция ключа находится в первых 2 строчках документации

"root иерархии классов Kotlin. Каждый класс Kotlin имеет Любой как суперкласс. "

Но он создает этот парадокс, когда T действительно не наследует от Any, потому что это не класс, но, с другой стороны, он будет классом при его использовании.

Я новичок в Kotlin, поэтому, я думаю, я просто не совсем понимаю концепцию Any или не совсем понимаю что-то в концепции Generi c.

Ответы [ 2 ]

1 голос
/ 28 февраля 2020

Обращаясь к вопросу о Any:

Это касается обнуляемости.

В найденной вами документации речь идет о классах , но не о типы ; Различие тонкое, но важное. (Даже в Java эти вещи не совсем одинаковы; например, List - это класс, но List<String> - это тип.)

В Kotlin обнуляемость является частью система типов. Таким образом, в то время как Any является самым верхним классом (соответствует Java s Object), оба типа Any и Any? являются типами: разница в том, что только последний может содержать null. Это делает Any подтипом Any? и Any? самым верхним типом.

Ваш пример имеет тип T?, который может иметь значение null, и поэтому не является подтипом Any, который не так.

Однако, это не единственное, что происходит в вашем вопросе; в приведенном вами коде T? должен быть супертипом из Any - что явно не так. (Я также озадачен попыткой параметризовать только возвращаемое значение. Как компилятор должен выводить фактический тип T в каждом вызове?)

1 голос
/ 28 февраля 2020

Вы, вероятно, сделали Java раньше, верно? Any является Kotlin эквивалентом Javas Object, что означает, что в Kotlin каждый объект неявно наследуется от Any, или, другими словами, Any может использоваться в качестве заполнителя для any возможный класс.

В вашем случае вы могли бы попробовать разыграть ваш результат, я думаю, что это сработает:

requestContent = call.receive() as T

Эта строка означает, вы знаете, что call.receive() действительно является объектом класс T или его подкласс. Это приведет к ошибке, если это предположение неверно.

// Редактировать: более понятный пример наследования.

Возьмите следующий пример, у вас есть класс Animal и два подкласса Dog и Cat. Теперь ваш график наследования выглядит следующим образом:

         Animal
        /      \
       /        \
      V          V
     Dog        Cat

Итак, это говорит: каждая кошка - животное, а каждая собака - животное. Но если у вас есть животное, вы не можете сказать, собака это или кошка.

В вашем конкретном случае c, Any - это класс Animal, а fe Dog - это ваш T. Так что T действительно наследуется от Any, но вы не знаете, действительно ли это T или, может быть, что-то еще, но если вы знаете, что в этом конкретном c случае это T, вы можете брось его.

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