将一些值连接到可变参数数组
Concatenate some value(s) to a vararg parameter array
我一直在尝试填补以下函数中的空白 (val args = ...
)。尝试了我能想到的一切并找到了一个非常复杂的解决方案。我觉得有更好的方法,请提出更符合 Kotlin 风格的方法。我错过了 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)
}
我大多数时候遇到的编译错误是这样的:
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
注意:return this.execute(*tasks, "--debug")
可以,如果没有打印,and/or代码重复是可以接受的。
这是泛型问题。 Kotlin 中的数组是不变的,Java 不是这种情况,例如
文档说:
fun <T> asList(vararg ts: T)
"Inside a function a vararg
-parameter of type T
is visible as an array of T
, i.e. the ts variable in the example above has type Array<out T>
."
一个Array<out T>
只能作为T
的生产者,不能添加个元素。 +
映射到的运算符仅在 Array<T>
上定义,即没有 out
修饰符。
您可以改为让方法接受 tasks: Array<String>
,它不使用任何投影并允许数组也用作使用者。
啊哈!找到了一个 "better" 解决方案,尽管它没有使用 +
:
val args = arrayOf(*tasks, "--debug")
s1m0nw1's clarifying 让我再次检查声明,我注意到参数是 <out T>
:
public operator fun <T> Array<T>.plus(elements: Array<out T>): Array<T>
可能有用:
val args = arrayOf("--debug") + tasks
它强制自定义部分在前面,这在我的情况下有效,但一般情况下可能无效。
我一直在尝试填补以下函数中的空白 (val args = ...
)。尝试了我能想到的一切并找到了一个非常复杂的解决方案。我觉得有更好的方法,请提出更符合 Kotlin 风格的方法。我错过了 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)
}
我大多数时候遇到的编译错误是这样的:
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
注意:return this.execute(*tasks, "--debug")
可以,如果没有打印,and/or代码重复是可以接受的。
这是泛型问题。 Kotlin 中的数组是不变的,Java 不是这种情况,例如
文档说:
fun <T> asList(vararg ts: T)
"Inside a function a
vararg
-parameter of typeT
is visible as an array ofT
, i.e. the ts variable in the example above has typeArray<out T>
."
一个Array<out T>
只能作为T
的生产者,不能添加个元素。 +
映射到的运算符仅在 Array<T>
上定义,即没有 out
修饰符。
您可以改为让方法接受 tasks: Array<String>
,它不使用任何投影并允许数组也用作使用者。
啊哈!找到了一个 "better" 解决方案,尽管它没有使用 +
:
val args = arrayOf(*tasks, "--debug")
s1m0nw1's clarifying <out T>
:
public operator fun <T> Array<T>.plus(elements: Array<out T>): Array<T>
可能有用:
val args = arrayOf("--debug") + tasks
它强制自定义部分在前面,这在我的情况下有效,但一般情况下可能无效。