Kotlin: ошибка компиляции, когда массив CharSequence и массив String в качестве аргумента - PullRequest
3 голосов
/ 09 апреля 2020

Вот моя функция:

fun setSingleChoiceItems(items: Array<CharSequence>?, checkedItem: Int,
        listener: DialogInterface.OnClickListener?) {
    // ...
}

Я пытался вызвать его с помощью массива строк (преобразованного из списка):

val str = listOf("1", "2", "3")
dialog.setSingleChoiceItems(str.toTypedArray(), currentChoice, null)

Моя среда IDE не выдает ошибок или предупреждений, но я столкнулся с ошибка компиляции: None of the following functions can be called with the arguments supplied.

Я попытался добавить вспомогательную функцию для принятия массива String:

fun setSingleChoiceItems(items: Array<String>?, checkedItem: Int,
        listener: DialogInterface.OnClickListener?) {
    // Here's a warning: No cast needed
    val cs = items?.map { it as CharSequence }?.toTypedArray()
    setSingleChoiceItems(cs,checkedItem,listener)
}

Теперь он может успешно скомпилироваться, но я столкнулся с ошибкой IDE: Overload resolution ambiguity. All these functions match.

Кажется, что единственный правильный способ - явное преобразование при вызове - без удобства метода. Очевидно, это очень хлопотно.

Так, как лучше всего решить эту проблему?

1 Ответ

3 голосов
/ 09 апреля 2020

Вы используете инвариантный тип для массива, поэтому он не может принимать и CharSequence и String. Предполагая, что эта функция только читает из массива, вы можете сделать тип ковариантным. Array<String> квалифицируется как Array<out CharSequence>, поскольку String реализует CharSequence.

fun setSingleChoiceItems(items: Array<out CharSequence>?, checkedItem: Int,
                         listener: DialogInterface.OnClickListener?) {
    // ...
}

Однако, если вам также необходимо записать в массив, он не может быть ковариантным. В этом случае вы можете ссылаться на него в общем виде c, и вам придется приводить к типу, например так:

@Suppress("UNCHECKED_CAST")
fun <T: CharSequence> setSingleChoiceItems(items: Array<T>?, checkedItem: Int,
                         listener: DialogInterface.OnClickListener?) {
    // ...

    // If writing to the array, you must cast
    if (items != null) items[0] = "Hello" as T
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...