我一直试图在下面的函数中填补空白(val args = ...
)。尝试了我能想到的一切,并找到了一个非常复杂的解决方案。我觉得有更好的方法,请建议更多的Kotlin-y方式。我错过了概念/操作员/乐趣/类型吗?
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")
可以使用,如果没有打印,和/或代码重复是可以接受的。
答案 0 :(得分:3)
啊哈!找到一个“更好”的解决方案,虽然它没有使用+
:
val args = arrayOf(*tasks, "--debug")
答案 1 :(得分:2)
这是一个泛型问题。 Kotlin中的数组是不变的,例如Java的情况就不是这样了。
文档说:
fun <T> asList(vararg ts: T)
&#34;在函数内部
vararg
-T
类型的参数作为T
的数组可见,即上例中的ts变量的类型为{{1} }}&#34;
Array<out T>
只能作为Array<out T>
的制作人,添加元素是不可能的。 T
映射到的运算符仅在+
上定义,即没有Array<T>
修饰符。
您可以使方法接受out
,而不使用任何投影,并允许数组也用作消费者。
答案 2 :(得分:0)
s1m0nw1澄清comment让我再次查看声明,我注意到该参数是public static int GetValueBeforeDot(string input){
return int.Parse(input.Substring(0, input.IndexOf('.'))
.Where(char.IsDigit)
.Aggregate(string.Empty, (e, a) => e + a));
}
:
<out T>
可能有用:
public operator fun <T> Array<T>.plus(elements: Array<out T>): Array<T>
它强制自定义部件位于前面,这在我的情况下有效,但可能不是一般。