Почему переведенный код Котлина жалуется на массив<BaseData>? быть массивом<out BaseData>

Наличие java-класса, использование androidStudio для перевода на kotlin. Получил ошибку и не уверен, как правильно ее перевести.

Java-код:

public class BaseDataImpl extends BaseData {

    private final BaseData[] translators;

    public BaseDataImpl(final BaseData... translators) {
        this.translators = cloneArray(translators);
    }

    public static <T> T[] cloneArray(final T[] array) {
        if (array == null) {
            return null;
        }
        return array.clone();
    }

}

после перевода кода получена ошибка: required Array<BaseData>?, found Array<out BaseData>, но translators в cloneArray<BaseData>(translators) вызов определяется как val translators: Array<BaseData>?,

кто-нибудь может помочь объяснить?

class BaseDataImpl(vararg translators: BaseData) : BaseData() {

    private val translators: Array<BaseData>?

    init {
        this.translators = cloneArray<BaseData>(translators)  //<=== error:  required Array<BaseData>?, found Array<out BaseData>
    }

    companion object {
        fun <T> cloneArray(array: Array<T>?): Array<T>? {
            return array?.clone()
        }
    }

}

1 ответ

Решение

Это написано в справочнике функций Kotlin относительно varargs:

Внутри функции vararg-параметр типа T виден как массив Tто есть ts переменная в приведенном выше примере имеет тип Array<out T>,

где указанная функция была:

function <T> asList(vararg ts: T): List<T>

Так что в вашем случае вы на самом деле передать Array<out BaseData> но вы принимаете только массив типа Array<T>? (в твоем случае Array<BaseData>). Либо вы адаптируете все типы к Array<out T> (что в основном похоже на высказывание List<? extends BaseData> в Java) или вы заботитесь о том, что вы имеете дело только с Ts вместо, например:

inline fun <reified T> cloneArray(array: Array<out T>?): Array<T>? {
        return array?.clone()?.map { it }?.toTypedArray()
}

Но посмотрите документацию, касающуюся этого: эталонные прогнозы Kotlin. Вы, вероятно, можете сделать это еще проще.

Другие вопросы по тегам