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 次 |
| 最近记录: |