I want to pass vararg from the buy function to the drive function but I get
a compile error:
required Array<T> found Array<out T>
code:
class Car
fun buy(vararg cars: Car) {
drive(cars) //compile error
}
fun drive(cars: Array<Car>) {
//...
}
Variable number of arguments (varargs)Only one parameter can be marked as vararg . If a vararg parameter is not the last one in the list, values for the subsequent parameters can be passed using named argument syntax, or, if the parameter has a function type, by passing a lambda outside the parentheses.
There are multiple ways of converting a Kotlin array to a vararg parameter. Firstly, we can simply pass an array with a spread operator to the function call. It's also possible to pass multiple arrays. Additionally, we can even combine literals and arrays to functions with vararg parameters.
The precise error is:
Type mismatch.
Required: Array<Car>
Found: Array<out Car>
The problem is that when you have a vararg cars: Car
function parameter, its type inside the function is Array<out Car>
, which basically represents a read-only array of the arguments the function was called with - after all, it wouldn't really be a nice thing to start modifying the arguments you got as a vararg
(function parameters in Kotlin are read-only val
s, and this is something very similar).
But your drive
function requires a regular Array<Car>
, which of course is writable as well. So if you wish to keep these function signatures, you'll need to create a new array that contains everything from your read-only array. This can be created using the following syntax:
drive(arrayOf(*cars))
This calls the arrayOf
function we usually create arrays with, which takes a vararg parameter, and uses the spread operator which is a way to pass in the elements of an array (which cars
is, inside the buy
function) as the vararg parameters (docs here).
While all this may sound complicated, it's actually a very efficient solution, as it just uses Array.copyOf
under the hood in the bytecode.
Another solution would be to change drive
to fun drive(Array<out Car>) { ... }
. This of course means that the cars inside drive cannot be modified but avoids the copying.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With