Как преобразовать список стираемых типов в массив в Котлин?

Функция toArray должна преобразовать список toArray в T который теперь является Array<String> .

 inline fun <reified T> toArray(list: List<*>): T { return list.toTypedArray() as T } toArray<Array<String>>(listOf("a", "b", "c")) // should be arrayOf("a", "b", "c") 

Однако toArray вызывает эту ошибку.

java.lang.ClassCastException: [Ljava.lang.Object; не может быть применено к [Ljava.lang.String;

У тебя есть идеи?

Проблема здесь в том, что вы на самом деле пытаетесь применить Object[] к String[] в терминах Java или Array<Any> to Array<String> в терминах Kotlin, но это разные объекты.

Итак, это утверждение:

 list.toTypedArray() 

возвращает Array<Any?> , а затем вы пытаетесь ClassCastException его в Array<String> и получить ClassCastException .

Как исправить?

Я предлагаю параметр типа прохода сам, и листинг List :

 inline fun <reified T> toArray(list: List<*>): Array<T> { return (list as List<T>).toTypedArray() } toArray<String>(listOf("1", "2")) 
  1. Я рекомендую вам оспаривать необходимость преобразования List<*> в типизированный массив (например, Array<String> ) вместо типизированного списка (например, List<String> ).

    Позднее можно сделать очень хорошо в Котлине:

     list.map { it as String } 

    Я рекомендую прочитать Разницу между типами List и Array в Kotlin и Java Practices -> Предпочитайте коллекции над более старыми классами .

  2. Если вы все еще чувствуете, что вам нужно работать с массивами, я рекомендую создать функцию «map», аналогичную функции Kotlin «map»:

     inline fun <T, reified R> List<T>.mapToTypedArray(transform: (T) -> R): Array<R> { return when (this) { is RandomAccess -> Array(size) { index -> transform(this[index]) } else -> with(iterator()) { Array(size) { transform(next()) } } } } 

    Затем вы можете эффективно преобразовать List<*> в типизированный массив:

     list.mapToTypedArray { it as String }