На этом шаге мы рассмотрим их использование при передаче аргументов в функцию.
До этого момента вы объявляли лямбды для передачи в аргументе другой функции. Сделать это можно иначе: передать ссылку на функцию. Ссылка на функцию преобразует именованную функцию (функцию, объявленную с ключевым словом fun) в значение, которое можно передавать как аргумент. Ссылку на функцию можно использовать везде, где допускается лямбда-выражение.
Чтобы увидеть ссылку на функцию, объявите новую функцию и дайте ей имя printConstructionCost.
. . . . . inline fun runSimulation(playerName: String, greetingFunction: (String, Int) -> String) { val numBuildings = (1..3).shuffled().last() // Случайно выберет 1, 2 или 3 println(greetingFunction(playerName, numBuildings)) } fun printConstructionCost(numBuildings: Int) { val cost = 500 println("construction cost: ${cost * numBuildings}") }
Рис.1. Объявление функции printConstructionCost() (SimVillage.kt)
Теперь добавьте в runSimulation() параметр costPrinter с типом функции и используйте его внутри runSimulation() для вывода стоимости строительства зданий.
inline fun runSimulation(playerName: String, costPrinter: (Int) -> Unit, greetingFunction: (String, Int) -> String) { val numBuildings = (1..3).shuffled().last() // Случайно выберет 1, 2 или 3 costPrinter(numBuildings) println(greetingFunction(playerName, numBuildings)) }
Рис.2. Добавление параметра costPrinter (SimVillage.kt)
Чтобы получить ссылку на функцию, используйте оператор :: с именем этой функции. Получите ссылку на функцию printConstructionCost и передайте ее как аргумент для нового параметра costPrinter в runSimulation().
fun main() { runSimulation("Guyal", ::printConstructionCost) { playerName, numBuildings -> val currentYear = 2021 println("Adding $numBuildings houses") "Welcome to SimVillage, $playerName! (copyright $currentYear)" } }
Рис.3. Передача ссылки на функцию (SimVillage.kt)
Запустите SimVillage.kt. Вы увидите, что в дополнение к количеству зданий теперь выводится и суммарная цена затрат на их строительство (рисунок 4).
Рис.4. Результат работы приложения
Ссылки на функцию полезны в ряде ситуаций. Если у вас есть именованная функция, которая соответствует параметру с типом функции, то вместо объявления лямбды можно использовать ссылку на функцию. Или, может быть, вы захотите передать в аргументе функцию из стандартной библиотеки.
На следующем шаге мы рассмотрим тип функции как возвращаемый тип.