使用扩展运算符将Array <string>作为varargs传递时的奇怪行为

时间:2018-08-21 06:38:19

标签: kotlin

我才刚刚开始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
}

这只是Android Studio的Java-Kotlin转换器从Java转换的代码的一部分。

错误出在函数调用中,如果我删除了散布运算符,编译器会说:

  

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

但是,当我将传播运算符放进去时,编译器会说:

  

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

我应该将vararg类型更改为vararg options: String?吗?

3 个答案:

答案 0 :(得分:0)

之所以会这样,是因为在Java中,任何String变量也可以为null。在Kotlin中,不可空变量(String)和空变量(String?)具有不同的类型。

根据您的情况,它取决于options[i].value是什么类型。如果永远不能为null,则可以将optionStrArr的类型更改为Array<String>,代码将正常工作。您可以通过以下方式创建Strings的数组:

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

如果options[i].value的类型为String?,则可以更改analyticPollReceive()的vararg类型,前提是该函数可以接收可为空的数组。否则,您必须重新考虑为什么要将一个可为null的数组传递给一个不希望使用null的函数。

答案 1 :(得分:0)

您看到的第二个错误是因为您使用arrayOfNulls<String>初始化了数组。这将创建一个Array<String?>,因为必须将其填充为空。

要解决此问题,请研究创建数组的其他方法,例如Collection#toTypedArrayArray#copyOf(取决于options的实际类型。
这些将生成与源类型相同的数组,并且不会隐式使其变为可空。

答案 2 :(得分:0)

数组的optionStrArr类型为Array<String?>
因此,您需要进行以下更改:

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