В своем выступлении « Составители – это базы данных» , Мартин Одерски представляет интересный случай угла отклонения:
class Tree[-T] { def tpe: T @uncheckedVariance def withType(t: Type): Tree[Type] }
T
определяется как контравариантный, поскольку полезно придумать типизированное дерево ( Tree[Type]
) как подтип нетипизированного дерева ( Tree[Nothing]
), но не наоборот.
Обычно компилятор Scala будет жаловаться на то, что T
появляется как возвращаемый тип метода tpe
. Вот почему Мартин закрывает компилятор с @uncheckedVariance
@uncheckedVariance.
Вот пример, переведенный в Котлин:
abstract class Tree<in T> { abstract fun tpe(): T abstract fun withType(t: Type): Tree<Type> }
Как и ожидалось, компилятор Kotlin жалуется на то, что T
появляется в позиции «out». Есть ли у Kotlin что-то похожее на @uncheckedVariance
? Или есть лучший способ решить эту конкретную проблему?
Kotlin имеет аннотацию @UnsafeVariance
которая эквивалентна @uncheckedVariance
в scala:
abstract class Tree<in T> { abstract fun tpe(): @UnsafeVariance T abstract fun withType(t: Type): Tree<Type> }