Подклассификация класса для изменения переменной параметра типа в Котлине

Этот вопрос вытекает из моего предыдущего вопроса о Generic Kotlin . Пожалуйста, посмотрите там дополнительную информацию о мотивации этого вопроса.

У меня есть класс, который принимает параметр неограниченного типа

trait Handler<T> { fun handle(result: T) } 

Мне нужно создать экземпляр Handler где T является List<O> , и поэтому является неизменным. Моя мысль заключалась в подклассе Handler и комментировании его как потребителя (т. Е. При использовании)

 trait ListHandler<in T>: Handler<List<T>> { } 

Однако это дает мне ошибку, которая говорит: «Параметр T объявлен как« in », но встречается в« инвариантном »положении в Handler<List<T> "

Что означает ошибка, и есть ли способ обойти ее?

Эта ошибка означает, что для всех компиляторов ваши объявления могут привести к сбою во время выполнения. Имейте в виду, что при проверке ListHandler компилятор не знает, какие члены определены внутри Handler , все, что он знает, – это то, что Handler был успешно проверен на соответствие типу и что его подпись говорит о том, что параметр типа является инвариантным. Это необходимо, потому что Handler может быть изменен позже и перекомпилирован без перекомпиляции ListHandler :

 trait Handler<T> { fun handle(result: T) fun get() : T } 

С таким заявлением легко написать фрагмент кода:

 // an ill-behaved ListHandler class HandlerImpl<T> : ListHandler<T> { private var storage: List<T> = listOf() override fun handle(result: List<T>) { storage = result } override fun get(): List<T> = storage } // Code using it, that breaks fun main(args: Array<String>) { val anyHandler = HandlerImpl<Any>() anyHandler.handle(listOf(1, 2, 3)) val problematic: ListHandler<String> = anyHandler // The following line requires an element to be a String, but it is an Int problematic.get()[0].length() } 

Результат:

 Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String 

Смотрите полный код здесь .

Intereting Posts
Как я могу сделать эту функцию функциональным способом программирования? kotlin – Как синтетическое свойство инициализирует представление? Использование функции чтения AudioRecord в Kotlin не соответствует аргументам типов платформ POSTING для API сервера с Kotlin (OkHttp / Retrofit) В Kotlin, как я могу обойти конфликты наследуемых объявлений, когда класс enum реализует интерфейс? Kotlin readBytes () никогда не завершает Неудачные тесты котлинских модулей после плагина 3.0 Возможно ли скомпилировать Kotlin Native без проверок времени выполнения? Vertx plus Kotlin coroutines вечно вешает travis ci build failing – причина: пространство PermGen Можно ли сохранить «Unit» в качестве возвращаемого типа функции Kotlin при вызове с Java? Что такое `it` в лямбда-тесте Котлин? Kotlin boxed Int – это не то же самое Кнопка Detect Back Нажмите кнопку в Android View Kotlin – Возможно ли инициализировать объект-компаньон перед блоком init в классе?