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

Tar*_*360 8 variadic-functions kotlin

我想将vararg从买入功能传递给驱动功能,但我得到了

编译错误:

required Array<T> found Array<out T>
Run Code Online (Sandbox Code Playgroud)

码:

class Car

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

fun drive(cars: Array<Car>) {
    //...
}
Run Code Online (Sandbox Code Playgroud)

zsm*_*b13 12

确切的错误是:

Type mismatch.
Required: Array<Car>
Found:    Array<out Car>
Run Code Online (Sandbox Code Playgroud)

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

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

drive(arrayOf(*cars))
Run Code Online (Sandbox Code Playgroud)

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

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

  • 我认为另一个答案更典型,您会喜欢将 `Array&lt;out Car&gt;` 作为第二个函数的参数,而不是复制。 (2认同)

小智 6

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