Kir*_*ill 5 generics variadic-functions kotlin
以下方法使用Java进行编译:
public class Main {
public static void main(String[] args) {
varargMethod(1, 2.0);
}
static void varargMethod(Number... va) {
arrayMethod(va);
}
static void arrayMethod(Number[] arr) {
for (Number number : arr) {
System.out.println(number);
}
}
}
Run Code Online (Sandbox Code Playgroud)
如果我尝试在Kotlin中编写类似的代码,则会出现类型不匹配错误:
fun main() {
varargFun(1, 2.0)
}
fun varargFun(vararg va: Number) {
arrayFun(va) // Error:(6, 14) Kotlin: Type mismatch: inferred type is Array<out Number> but Array<Number> was expected
}
fun arrayFun(arr: Array<Number>) {
arr.forEach {
println(it)
}
}
Run Code Online (Sandbox Code Playgroud)
我期望va
是这样的Array<String>
,但是是Array<out String>
。如果将其强制转换为:va as Array<Number>
,则会收到警告:
Warning:(6, 21) Kotlin: Unchecked cast: Array to Array
How am I supposed to pass vararg
as an Array
to another function without getting warning and errors?
The difference is that in Java arrays are covariant, i.e. the following is valid:
public static void main(String[] args) {
Number[] numbers = new Number[0];
Integer[] ints = new Integer[0];
numbers = ints;
}
Run Code Online (Sandbox Code Playgroud)
However, arrays are not covariant in Kotlin, i.e. the following gives a compilation error:
var numbers: Array<Number> = arrayOf()
val ints: Array<Int> = arrayOf()
numbers = ints // error: required Array<Number>, found Array<Int>
Run Code Online (Sandbox Code Playgroud)
但是,您可以使用关键字声明数组是一个生产器(即,您保证不会在其中插入任何内容;编译器将确保这样做)out
。这使数组成为协变的,即以下内容有效:
var numbers: Array<out Number> = arrayOf() // we will only extract Numbers out of this array
val ints: Array<Int> = arrayOf()
numbers = ints // this is ok
Run Code Online (Sandbox Code Playgroud)
鉴于此,如果vararg va: Number
未将其视为Array<out Number>
,则可以仅使用Number
对象而不是其子类来调用方法。即,以下操作将失败:
fun main() {
varargFun(arrayOf<Int>(1, 2)) // error: required Array<Number>, found Array<Int>
}
fun varargFun(va: Array<Number>) {
arrayFun(va)
}
Run Code Online (Sandbox Code Playgroud)
但同样,有一个out
(这是vararg
做),它神奇地运行:
fun main() {
varargFun(arrayOf<Int>(1, 2))
}
fun varargFun(va: Array<out Number>) {
arrayFun(va)
}
Run Code Online (Sandbox Code Playgroud)
在函数内部,
vararg
类型的参数T
作为 的数组可见T
,即上面示例中的 [...] 变量具有类型Array<out T>
。
问题的解决方案很简单:忽略 Kotlin 的护栏,并复制 arguments。
fun varargFun(vararg va: Number) {
val copy = arrayOf(*va)
arrayFun(copy)
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
106 次 |
最近记录: |