Scala Передача функции с аргументом

Пример Scala для передачи функции другой функции не имеет случая, когда переданная функция (timeFlies) принимает аргумент (x).

object Timer {
  def oncePerSecond(callback: (Int) => Unit) {
    while (true) { callback(x); Thread sleep 1000 }
  }
  def timeFlies(x: int) {
    println("time flies like an arrow...")
  }
  def main(args: Array[String]) {
    oncePerSecond(timeFlies(5))
  }
}

Как я могу заставить вышеуказанный код работать?

Изменить: я добавил x в oncepersecond, чтобы прояснить цель - передать целое число.

Ответы

Ответ 1

Есть как минимум два способа сделать это, в зависимости от того, где именно вы хотите передать аргумент. Первый способ - это сохранить main, как и у вас.

object Timer {
  def oncePerSecond(callback: => Unit) {
    while (true) { callback; Thread sleep 1000 }
  }
  def timeFlies(x: Int) {
    println("time flies like an arrow...")
  }
  def main(args: Array[String]) {
    oncePerSecond(timeFlies(5))
  }
}

Другой метод - передать параметр в точке обратного вызова, например:

object Timer {
  def oncePerSecond(callback: (Int) => Unit) {
    val x = 5
    while (true) { callback(x); Thread sleep 1000 }
  }
  def timeFlies(x: Int) {
    println("time flies like an arrow...")
  }
  def main(args: Array[String]) {
    oncePerSecond(timeFlies)
  }
}

Обратите внимание, что timeFlies имеет подпись (Int) => Unit, но timeFlies(5) имеет подпись => Unit, из-за частичного приложения. Это в основном означает, что вы можете применить параметр для автоматического создания функции, которая принимает меньше параметров. oncePerSecond должен знать в своей сигнатуре, если вы уже применили параметр Int к обратному вызову или нет.

Оба метода полезны для разных случаев использования. Первый способ позволяет oncePerSecond не знать о параметрах обратного вызова. Второй способ позволяет вам изменить значение x каждый раз через цикл, если вы хотите.

Ответ 2

Возвращаемый тип timeFlies будет Unit, а не Function. Возможно, вы имели в виду:

oncePerSecond(() => timeFlies(5))

Ответ 3

oncePerSecond(() => timeFlies(5))

или

def oncePerSecond(callback: => Unit) {...

Ответ 4

Параметр callback: () => Unit - это функция с нулевым параметром, которая возвращает Unit. Вы должны сделать это параметром по имени (что-то, что соответствует Unit):

def oncePerSecond(callback: => Unit) = ...