в котлине как поставить ссылку на функцию в массиве - PullRequest
1 голос
/ 07 мая 2019

Имея функцию-член класса, такую ​​как:

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 ...

if do:

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 Ответ

4 голосов
/ 07 мая 2019

Первая попытка не удалась, потому что ArrayList не имеет конструктора, принимающего (список переменных аргументов) значений.

Вы можете получить почти такой же эффект, заменив ArrayList с listOf() (или, если вам нужна изменчивость, mutableListOf()), так как принимает список переменных:

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

Это, пожалуй, самое естественное решение.(Тем не менее, mutableListOf() гарантированно вернет только реализацию MutableList; это не может быть ArrayList.)

Вторая попытка не удалась, поскольку она создаетпустой список.

(Используемый им конструктор ArrayList принимает параметр с именем initialCapacity; он гарантирует, что список может занять как минимум 3элементам без необходимости перераспределять его массивы, но его начальный размер равен нулю.)

Возможно, путаница заключается в том, что, хотя вы говорите, что «хотели бы добавить массив ссылок на функции», вы создаетеList, а не Array.

(Класс ArrayList является реализацией интерфейса List, который использует внутренний массив. Это соответствует Java-соглашению о присвоении именклассы реализации как <Implementation><Interface>.)

Если вам нужно создать фактический массив, вы можете использовать arrayOf() в первом примере:

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

Спискивероятно, используются более широко, чем массивы в Kotlin, так как они более гибкиеле.(Вы можете выбирать между многими различными реализациями с различными характеристиками. Они лучше работают с универсальными типами; например, вы можете создать List универсального типа. Вы можете сделать их неизменяемыми. И, конечно, если они изменчивы, ониможет расти и уменьшаться.)

Но массивы тоже имеют свое место, особенно если важна производительность, вам необходимо взаимодействовать с кодом, использующим массив, и / или размер фиксирован.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...