Как справляться с общими границами, переносящимися с Java на Kotlin?

Моя цель состоит в том, чтобы методы интерфейса принимали тип класса реализации. Вот код, который я написал до сих пор:

internal interface Diff<Diff> { //in Java I was using <? extends Diff> fun lessThan(other: Diff): Boolean } private class ADiff(private val value: Int) : Diff<ADiff> { override fun lessThan(other: ADiff): Boolean { return value < other.value } } //B can now accept even int types which is not desired private class BDiff(private val value: Int) : Diff<Int> { override fun lessThan(other: Int): Boolean { return value < other } } 

Причина, по которой это «работало» на Java, состояла в том, что <T extends Diff> использует необработанный тип Diff . Не делай этого!


Самое близкое, что вы можете получить, это использовать рекурсивную привязку типа:

 interface Diff<T : Diff<T>> { fun lessThan(other: T): Boolean } 

Проблема в том, что вы можете заменить любой другой подтип Diff .

Однако при использовании Diff используйте ограничение типа T : Diff<T> :

 fun <T : Diff<T>> diffUser(diff1: T, diff2: T) { println(diff1.lessThan(diff2)) } 

и любой Diff , который не реализует Diff<SameType> , не будет принят.

Пример:

 class CDiff(private val value: Int) : Diff<DDiff> { // <-- Wrong type! override fun lessThan(other: DDiff) = value < other.value } class DDiff(val value: Int) : Diff<DDiff> { override fun lessThan(other: DDiff) = value < other.value } fun test() { diffUser(CDiff(3), CDiff(4)) // <-- Doesn't compile due to the generic constraint diffUser(DDiff(3), DDiff(4)) } 

Этот же подход используется классом Comparable .


Хотя это работает, то, что вы действительно хотите, это «тип», и это не поддерживается, хотя в какой-то момент оно было на дорожной карте . Я считаю, что JetBrains отклонил запрос на это, хотя я не могу найти отчет об ошибке.

В этом ответе описывается обходной путь в Java с использованием шаблона CRT , хотя он не обязательно безопасен по типу.

Intereting Posts
Джексон-десериализация – классы данных Kotlin – значения по умолчанию для отсутствующих полей на картографе Anko DSL пересматривает странное поведение при добавлении элементов Ошибка ввода типа: недостаточно информации для параметра infer. Пожалуйста, укажите это явно Котлинские мутаторы Разделить список на части Анимация (прокрутка) одна ViewGroup блокирует несвязанные виды из анимации до завершения предупреждение: файлы JAR Kotlin для запуска в пути к классам должны иметь одну и ту же версию Kotlin null от Java Ссылка конструктора Котлина с дженериками Как использовать библиотеку androidannotations в kotlin? VertX Web не удаляет файлы cookie Использование lambda в пользовательском BindingAdapter с использованием Android Databinding и Kotlin Android Kotlin не может использовать list.sort () с lambda java.lang.IllegalArgumentException: Callable ожидает 4 аргумента, но 3 предоставлены Как правильно обращаться с ошибками при использовании HTTP-клиента в Котлине?