如何将vararg作为数组传递给Kotlin?

时间:2017-05-20 19:28:25

标签: kotlin variadic-functions

我想将vararg从buy函数传递给驱动函数 但是我得到了

编译错误:

required Array<T> found Array<out T>

代码:

class Car

fun buy(vararg cars: Car) {
    drive(cars) //compile error
}

fun drive(cars: Array<Car>) {
    //...
}

5 个答案:

答案 0 :(得分:7)

准确的错误是:

Type mismatch.
Required: Array<Car>
Found:    Array<out Car>

问题在于,当你有一个vararg cars: Car函数参数时,它在函数内的类型是Array<out Car>,它基本上代表了调用函数的参数的只读数组 - 毕竟,开始修改你得到的vararg参数并不是一件好事(Kotlin中的函数参数是只读的val,这是非常相似的)。

但是您的drive函数需要常规Array<Car>,这当然也是可写的。因此,如果您希望保留这些函数签名,则需要创建一个包含只读数组中所有内容的新数组。可以使用以下语法创建:

drive(arrayOf(*cars))

这调用我们通常创建数组的arrayOf函数,它接受一个vararg参数,并使用扩展运算符,这是一种传递数组元素的方法(cars是,在buy函数内部)作为vararg参数(docs here)。

虽然这一切听起来很复杂,但它实际上是一个非常有效的解决方案,因为它只是在字节码中使用Array.copyOf

答案 1 :(得分:2)

另一种解决方案是将drive更改为fun drive(Array<out Car>) { ... }。这当然意味着驱动器内部的汽车无法修改,但避免了复制。

答案 2 :(得分:0)

从根本上说,你需要在变量名之前使用vararg键。

fun args(vararg cars: Car) {
   //use cars as an array 
}

答案 3 :(得分:0)

override fun checkMatch(vararg cards: SetsCard): Int {
    return if (isSet(*cards)) 16 else -2
}

private fun isSet(vararg cards: SetsCard) : Boolean {
    if (cards.size == 3) {
        return true
    }
    return false
}

答案 4 :(得分:0)

fun foo(vararg strings: String): Array<out String> {
    return strings
}

//  Define a var 
var yourVar: Array<out String> = foo("a", "b", "c")

// Use var in Java method `public void javaMethod(String... someParam)() {}`
javaMethod(*yourVar)