it-swarm.com.ru

Функция прохождения 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))
  }
}

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

Правка: я добавил х в раз в секунду, чтобы уточнить цель, чтобы передать целое число.

17
BAR

Есть как минимум два способа сделать это, в зависимости от того, куда именно вы хотите передать аргумент. Первый способ - это то, где вы сохраняете 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 каждый раз через цикл, если хотите.

22
Karl Bielefeldt

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

oncePerSecond(() => timeFlies(5))
3
John

oncePerSecond(() => timeFlies(5))

или же

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

2
Ryoichiro Oka

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

def oncePerSecond(callback: => Unit) = ...
0
Michael Zajac