Безопасный свободный отлив в Kotlin? - PullRequest
0 голосов
/ 29 февраля 2020

Имея эти функции расширения:

inline fun <reified OUT> Any.cast(): OUT = this as OUT
inline fun <reified IN, reified OUT: IN> IN.downcast(): OUT = this as OUT
inline fun <reified IN: OUT, reified OUT> IN.upcast(): OUT = this as OUT

Я могу использовать их следующим образом:

val x1: Number = 42
val x2: String = "abc"
val x3: Double = 3.14

val y1: Int = x1.downcast<Number, Int>()
val y2: CharSequence = x2.upcast<String, CharSequence>()
val y3: Float = x3.cast<Float>() // dangerous, crash

Проблема first в том, что я должен написать:

x1.downcast<Number, Int>()

Вместо

x1.downcast<Int>()

Проблема second заключается в том, что даже если бы я достиг синтаксиса x1.upcast<Int>(), параметр IN generi c можно было бы легко вывести как Any, так что он всегда будет работать, что нежелательно.


Пример ниже показывает упрощенный плохой сценарий реальной жизни:

interface A1Able
class B1Impl : A1Able { val desiredField = 42 }
class C1Impl : A1Able

interface A2Able
class B2Impl : A2Able { val someField: A1Able = C1Impl() }
class C2Impl : A2Able { val someField: A1Able = B1Impl() }

interface A3Able
class B3Impl : A3Able { val someField: A2Able = C2Impl() }
class C3Impl : A3Able { val someField: A2Able = B2Impl() }

interface A4Able
class C4Impl : A4Able { val someField: A3Able = B3Impl() }

fun main() {
  val source: A4Able = C4Impl()
  val desiredField = ((((source as C4Impl).someField as B3Impl).someField as C2Impl).someField as B1Impl).desiredField
}

И это то, что я называю скобка, ад . С помощью синтаксиса я пытаюсь добиться этого, как показано ниже (небезопасная версия приведения):

source.cast<C4Impl>().someField.cast<B3Impl>().someField.cast<C2Impl>().someField.cast<B1Impl>().desiredField

Несмотря на то, что это не более короткий синтаксис, он гораздо более читабелен и отсутствует скобка ад . Проблема состоит в том, что я теряю проверку типов таким образом, поэтому я мог бы написать "abc".cast<Int>() и вызвать исключение.


Как я могу сделать это безопаснее и сохранить свободный синтаксис?

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