在kotlin中如何将函数引用放入数组

时间:2019-05-06 21:10:39

标签: kotlin function-reference

具有类成员函数,例如:

private fun getData1(uuid:String): IData? {
    ...
}
private fun getData2(uuid:String): IData? {
    ...
}
private fun getData3(uuid:String): IData? {
    ...
}

,并希望放入一个函数引用数组:

var funArray = ArrayList<(uuid: String) -> IData?> (
     this::getData1, 
     this::getData2, 
     this::getData3)

它不能编译:

None of the following functions can be called with the arguments 
supplied: 
public final fun <E> <init>(): kotlin.collections.ArrayList<(uuid: String) -> IData?> /* = java.util.ArrayList<(uuid: String) -> IData?> */ defined in kotlin.collections.ArrayList ...

如果这样做:

var funArray: ArrayList<(uuid: String) -> IData?> = ArrayList<(uuid: String) -> IData?>(3)

funArray[0] = this::getData1 //<== crash at here
funArray[1] = this::getData2
funArray[2] = this::getData3

异常崩溃

java.lang.IndexOutOfBoundsException: Index: 0, Size: 0

如何将函数引用放入数组中?

1 个答案:

答案 0 :(得分:4)

第一次尝试失败,因为ArrayList没有构造函数采用(可变参数列表)值。

ArrayList替换为listOf()(或者,如果需要可变性,则mutableListOf()),可以达到几乎相同的效果,就像 变量列表:

var functions = listOf<(uuid: String) -> IData?>(
    this::getData1, 
    this::getData2, 
    this::getData3)

这也许是最自然的解决方案。 (但是,只能保证mutableListOf()返回一个MutableList实现;它可能不是ArrayList。)

第二次尝试失败,因为它正在构造一个空列表。

(它使用的ArrayList constructor带有一个称为initialCapacity的参数;它确保列表可以至少包含3个元素,而无需重新分配其数组,但其初始大小为零。)

也许这是因为尽管您说“想放入函数引用数组”,但您是在创建List,而不是Array

ArrayList类是List接口的实现,该接口恰好在内部使用数组。这遵循Java约定将实现类命名为 <Implementation><Interface> 。)

如果需要创建实际的数组,可以在第一个示例中使用arrayOf()

var functions = arrayOf<(uuid: String) -> IData?>(
    this::getData1, 
    this::getData2, 
    this::getData3)

列表在Kotlin中的使用可能比数组更广泛,因为它们更灵活。 (您可以在具有不同特征的许多不同实现之间进行选择。它们与泛型一起使用效果更好;例如,您可以创建泛型类型的List。可以使它们不可变。当然,如果它们是可变的。 ,它们可以成长和收缩。)

但是数组也有其位置,特别是在性能很重要的情况下,您需要与使用数组的代码进行互操作,并且/或者大小是固定的。