Я только начал Kotlin и теперь должен выяснить кое-что о функции, требующей varargs типа String. Проблемный код выглядит следующим образом:

val optionStrArr = arrayOfNulls<String>(options.size)
for (i in options.indices) {
    optionStrArr[i] = options[i].value
}
App.instance?.analyticPollReceive(pollID!!, title!!, question!!, *optionStrArr)

...

fun analyticPollReceive(id: String, title: String, question: String, vararg options: String) {
    // function body
}

Это только часть кода, который был конвертирован из Java с помощью Android Studio Java-Kotlin converter.

Ошибка в вызове функции, где, если я уберу оператор распространения, компилятор скажет:

Type mismatch. Required: String; Found: Array<String?>

Однако, когда я помещаю этот оператор распространения, компилятор говорит:

Type mismatch. Required: Array<out String>; Found: Array<String?>

Должен ли я просто изменить тип vararg на vararg options: String??

1
Gensoukyou1337 21 Авг 2018 в 09:38

3 ответа

Лучший ответ

Это происходит потому, что в Java любая переменная String также может иметь значение null. В Kotlin у вас есть разные типы для переменных, отличных от nullable (String) и nullabe (String?).

В вашем случае это зависит от типа options[i].value. Если это никогда не может быть null, тогда вы можете изменить тип optionStrArr на Array<String>, и код будет работать нормально. Вы можете создать массив Strings следующим образом:

val optionStrArr = Array<String>(options.size) { options[it].value }

Если options[i].value имеет тип String?, то вы можете либо изменить тип vararg analyticPollReceive(), если для этой функции имеет смысл получать массив, допускающий значение NULL. В противном случае вам придется переосмыслить, почему у вас есть обнуляемый массив, который вы хотите передать функции, которая не хочет нулей.

0
rozina 21 Авг 2018 в 07:20

Вторая ошибка, которую вы видите, состоит в том, что вы инициализируете массив с arrayOfNulls<String>. Это создаст Array<String?>, так как он должен быть заполнен нулями.

Чтобы исправить это, найдите другие способы создания массива, такие как Collection#toTypedArray или Array#copyOf (в зависимости от того, какой тип options на самом деле.
Они сгенерируют массив того же типа, что и источник, и не сделают его неявным образом обнуляемым.

0
RobCo 21 Авг 2018 в 07:22

Тип массива optionStrArr - Array<String?>.
Поэтому вам нужно внести это изменение:

fun analyticPollReceive(id: String, title: String, question: String, vararg options: String?) {
    // function body
}
0
user8959091user8959091 21 Авг 2018 в 07:24
51942941