Можно ли изменить массив <T>на IntArray, FloatArray, CharArray ... ECT, автоматически используя Generi c in Kotlin? - PullRequest
0 голосов
/ 25 февраля 2020

Я новичок в Kotlin и изучаю эту книгу.

Функциональный Kotlin: Расширьте свои навыки OOP и внедрите функциональные техники в Kotlin и Arrow

Эта книга содержит следующие коды:

sealed class FunList<out T> {
  object Nil: FunList<Nothing>()
  data class Cons<out T>(val head: T, val tail: FunList<T>): FunList<T>
}

fun initListOf(vararg numbers: Int): FunList<Int> {
  return if (numbers.isEmpty()) {
    Nil
  } else {
    Cons(numbers.first(), initListOf(*numbers.drop(1).toTypedArray().toIntArray()))
  }
}

Это пример построения структуры данных. Это пример построения структуры данных. Я задавался вопросом, могу ли я использовать обобщенный c типа, который входит в FunList в initListOf функцию. Например:

fun <T> initListOf(vararg items: T): FunList<T> = if (items.isEmpty()) {
  Nil
} else {
  Cons(items.first(), initListOf(*items.drop(1).toTypedArray())) // error
}

Но код не работает. Причина в том, что если я поместил фактор того же типа в параметр varag, он был преобразован в IntArray, FloatArray, LongArray и CharArray, который был распознан как тип, отличный от TypedArray ( Array<T>).

Как заставить их автоматически создавать один и тот же тип FunList, когда я помещаю переменную того же типа? Это просто академи c любопытство.

Ответы [ 2 ]

0 голосов
/ 25 февраля 2020

Это выглядит не очень красиво, но вы можете сделать следующее

fun <T> initListOf(items: Array<T>): FunList<T> = when {
    items.isEmpty() -> FunList.Nil
    items.size == 1 -> {
        FunList.Cons(items.first(), initListOf(items.copyOf(0) as Array<T>))
    }
    else -> {
        FunList.Cons(items.first(), initListOf(items.copyOfRange(1, items.size)))
    }
}

, а затем вы можете назвать его как

initListOf(arrayOf(1,2,3,4,5))
0 голосов
/ 25 февраля 2020

Varags и типизированные массивы работают более хитроумно, чем списки, если использовать их обобщенно c, потому что они имеют типизированные типы (без стирания типов). Таким образом, вы можете перегрузить вашу функцию версией, которая вместо этого принимает параметр List:

fun <T> initListOf(items: List<T>): FunList<T> = if (items.isEmpty()) {
    Nil
} else {
    Cons(items.first(), initListOf(items.drop(1)))
}

fun <T> initListOf(vararg items: T) = initListOf(items.toList())
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...