在函数参数

时间:2019-10-08 14:06:22

标签: generics kotlin

我想要一个可以接受不同类型ArrayList并对其进行一些操作的函数。例如,我想打印数组的所有元素。我已经尝试过了:

val numbers by lazy {ArrayList<Int>(0)}
val texts by lazy {ArrayList<String>(0)}

fun main() {
    numbers.add(1)
    numbers.add(2)
    numbers.add(3)
    texts.add("one")
    texts.add("two")
    texts.add("three")
    printAll(numbers)    //error here
    printAll(texts)      //error here
}

fun printAll(values: ArrayList<Any>){
    values.forEach{item ->
        println(item)
    }
}

但是我收到此错误:

Type mismatch: inferred type is kotlin.collections.ArrayList<Int> /* = java.util.ArrayList<Int> */ but kotlin.collections.ArrayList<Any> /* = java.util.ArrayList<Any> */ was expected
Type mismatch: inferred type is kotlin.collections.ArrayList<String> /* = java.util.ArrayList<String> */ but kotlin.collections.ArrayList<Any> /* = java.util.ArrayList<Any> */ was expected

这是我想要做的简化版本。在我的实际实现中,参数values是从不同的回调函数接收的,我需要对元素进行更复杂的处理,而不仅仅是打印。

我应该在function参数中尝试什么?谢谢。

2 个答案:

答案 0 :(得分:3)

这可以通过在方法签名中将Any前缀out来解决。

fun printAll(values: ArrayList<out Any>){
    values.forEach{item ->
        println(item)
    }
}

了解更多:

https://kotlinlang.org/docs/reference/generics.html

https://kotlinexpertise.com/kotlin-generics-and-variance-vs-java/

答案 1 :(得分:3)

您可以使用Generic Functions。在您的示例中,只需将函数更改为:

fun <T> printAll(values: ArrayList<T>) {...}

和kotlin编译器会将T更改为任何类型,您将使用。您应该阅读有关泛型的知识-在面向对象的编程中它非常有用。

现在,您可以使用与以前完全相同的方法,因为编译器将为您确定T的类型。