Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Concatenate some value(s) to a vararg parameter array

I've been trying to fill in the gap (val args = ...) in the below function. Tried everything I could think of and found a pretty convoluted solution. I have a feeling there's a better way, please suggest a more Kotlin-y way. Am I missing a concept/operator/fun/type?

class Result
interface Runner { fun execute(vararg tasks: String): Result }

fun Runner.debugExec(vararg tasks: String): Result {
// red: compile errors, mostly 
    //val args = tasks + "--debug" 
    //val args: Array<String> = tasks + "--debug"
    //val args: Array<out String> = tasks + "--debug"
    //val args = tasks + arrayOf("--debug")
    //val args = tasks + arrayOf<String>("--debug")
    //val args = tasks + listOf("--debug")
    //val args = tasks + (arrayOf("--debug") as Array<out String>)
    //val args = tasks + arrayOf<out String>("--debug") // Projections are not allowed here
    //val args = tasks.toList() + "--debug" // spread operator doesn't work
    //val args = tasks.plusElement("--debug") // cannot infer
    //val args = "--debug" + tasks // it's .toString() and spread operator doesn't work
// yellow: works, but warns
    //val args = (tasks as Array<String>) + "--debug" // unchecked cast
// green: but we must be able to do better, it's kotlin after all! 
    //val args = (tasks.toList() + "--debug").toTypedArray() // too many method calls
    println(args)
    return this.execute(*args)
}

The compile error I get most of the time is something like:

None of the following functions can be called with the arguments supplied.
Array<T>.plus(T)
  where T cannot be inferred for
    operator fun <T> Array<T>.plus(element: T): Array<T> defined in kotlin.collections
Array<out String>.plus(Array<out String>)
  where T = CapturedTypeConstructor(out String) for
    operator fun <T> Array<T>.plus(elements: Array<out T>): Array<T> defined in kotlin.collections
Array<out String>.plus(Collection<String>)
  where T = CapturedTypeConstructor(out String) for
    operator fun <T> Array<T>.plus(elements: Collection<T>): Array<T> defined in kotlin.collections

Note: return this.execute(*tasks, "--debug") would work, if there was no printing, and/or code duplication would be acceptable.

like image 279
TWiStErRob Avatar asked Jan 29 '23 19:01

TWiStErRob


1 Answers

Aha! Found one "better" solution, though it's not using +:

val args = arrayOf(*tasks, "--debug")
like image 198
TWiStErRob Avatar answered Jan 31 '23 09:01

TWiStErRob