为什么翻译的kotlin代码抱怨Array <basedata>?成为Array <out basedata =“”>

时间:2018-08-06 15:27:25

标签: kotlin kotlin-generics

具有一个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 个答案:

答案 0 :(得分:3)

它写在Kotlin function reference regarding varargs中:

  

在函数内,类型为T的vararg参数可以看到为T的数组,即,上面示例中的ts变量的类型为Array<out T>。 / p>

引用的函数为:

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

因此,在您的情况下,您实际上传递了一个Array<out BaseData>,但您仅接受类型为Array<T>?的数组(在您的情况下为Array<BaseData>)。您要么将所有类型都调整为Array<out T>(基本上类似于Java中的List<? extends BaseData>),要么注意只处理T,例如与:

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

但是请查询与此相关的文档:Kotlin generics reference - type projections。您可能可以更轻松地完成此操作。