Scala: вернуть ссылку на функцию
Я хотел бы иметь функции Scala, которые возвращают ссылку на другую функцию, возможно ли это?
Ответы
Ответ 1
Вы можете вернуть тип функции (это определяется A => B
). В этом случае Int в Int:
scala> def f(x:Int): Int => Int = { n:Int => x + n }
f: (x: Int)(Int) => Int
Когда вы вызываете функцию, вы получаете новую функцию.
scala> f(2)
res1: (Int) => Int = <function1>
Что можно назвать нормальной функцией:
scala> res1(3)
res2: Int = 5
Ответ 2
В одном направлении (несколько уникальном для функциональной объектной ориентации) вы можете использовать функции более высокого порядка - создавать свободные связи между объектами.
В приведенном ниже примере класс Alarm
имеет метод check4Danger()
, который проверяет, превышает ли вычисленное значение значение DangerLevel
. Класс Alarm ничего не знает об объектах, которые его называют.
Класс Car
имеет метод engineCrashRisk()
, который возвращает анонимную функцию, которая вычисляет риск сбоя двигателя. Car
не имеет зависимости от Тревоги.
case class Alarm(temperature: Double, pressure: Double){
val DangerLevel = 100000.0
def check4Danger( f: (Double, Double) => Double): Boolean = {
val risk = f(temperature, pressure)
if( risk > DangerLevel ){
println("DANGER: "+ risk )
true
}else{
println("Safe: " + risk)
false
}
}
}
case class Car(fuelRate: Double, milage: Int){
def engineCrashRisk() =
(temperature: Double, pressure: Double) =>
temperature * milage + 2*pressure / fuelRate
}
val car = Car(0.29, 123)
val riskFunc = car.engineCrashRisk
val alarm = Alarm(124, 243)
val risk = alarm.check4Danger(riskFunc)
Выход этого script:
Safe: 16927.862068965518
В этом примере мы использовали анонимные функции с закрытием для создания вызова метода без зависимостей между объектами Alarm
и Car
. Этот пример имеет смысл?