Как бы вы определили задержанный (по имени) параметр, который принимает функцию, которая принимает параметры? - PullRequest
2 голосов
/ 15 декабря 2009

Я видел delayed пример в книге Дэвида Поллака "Beginning Scala". Я пытался адаптировать это, методом проб и ошибок. Вот что у меня есть:

def sayhello() = {
  println("hello")
}

def delaying(t: => Unit):Unit = {
  println("before call")
  t
  println("after call")
}

delaying(sayhello())

Как бы вы задержали функцию / метод, принимающий параметры? Почему я не могу использовать паразиты, когда звоню t? Где я могу найти больше документации по функциям задержки?

Ответы [ 2 ]

5 голосов
/ 15 декабря 2009

t не обязательно должно быть значением функции. Это просто любое переданное по имени значение, которое оценивается как Unit.

Когда вы указываете t в функции delaying, вы явно не вызываете функцию, переданную в качестве этого параметра. Указав это, вы заставляете оценивать передаваемый по имени параметр, что означает, что sayhello() оценивается в этой точке.

Нет причин, по которым вы не можете использовать параметры в функциях в передаваемых по имени параметрах:

def say(word: String) {
  println(word)
}

def delaying(t: => Unit) {
  println("before call")
  t
  println("after call")
}

delaying(say("hello"))

Единственный раз, когда вы присоединяете параметры к t внутри delaying, это может быть, если его тип возвращаемого значения был (не Unit, а) типом функции, принимающим параметры.

1 голос
/ 16 мая 2010

Поскольку у меня ужасная память, а в ответе не приводится пример того, как на самом деле объявить параметр по имени, который возвращает функцию, принимающую один или несколько аргументов, я придумал следующее:

object DelayedEvalTest {

    private class DelayedFunction extends Function1[Int,Unit] {

        override def apply(x:Int) : Unit = {}

        println("function created")
    }

    private def eval(eval:Boolean, op : Int => Unit ) {
        println("in eval()")
        if ( eval ) {
            op( 42 )
        }
    }

    private def evalDelayed(eval:Boolean, op : => Int => Unit ) {
        println("in evalDelayed()")
        if ( eval ) {
            op( 42 )
        }
    }

    def main(args:Array[String]) {
        eval( false , new DelayedFunction() )
        evalDelayed( false , new DelayedFunction() )
    }

}
...