【问题标题】:How would you define a delayed (by-name) parameter that accepts a function that takes parameters?您将如何定义接受带参数的函数的延迟(按名称)参数?
【发布时间】:2009-12-15 17:26:23
【问题描述】:

我在 David Pollak 的 "Beginning Scala" 中看到了一个 delayed 示例。我试图通过反复试验来适应这一点。这是我所拥有的:

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

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

delaying(sayhello())

你会如何延迟一个带参数的函数/方法?为什么我在拨打t 时不能使用括号?在哪里可以找到更多关于延迟函数的文档?

【问题讨论】:

  • @DerekMahar 完成。请删除你的评论(我也会删除我的)。

标签: scala language-features delay


【解决方案1】:

t 不必是函数值。它只是计算为Unit 的任何按名称传递的值。

当您在 delaying 函数中声明 t 时,您并未显式调用作为该参数传递的函数。通过声明它,您将强制对按名称传递的参数进行评估,这意味着 sayhello() 在此时被评估。

没有理由不能在按名称传递的参数中使用函数中的参数:

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

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

delaying(say("hello"))

您将参数附加到tdelaying 的唯一情况是它的返回类型是(不是Unit 而是)带参数的函数类型。

【讨论】:

  • 我可以传递返回 Unit 以外的其他类型的东西吗?还是需要参数?如果是这样,您可以发布一个示例吗?
  • Geo,是的,您可以在别名参数中传递任何类型的值。我已经在我的回答中发布了一个带有参数的示例:请参阅我的 say 函数。
  • 随着 Scala 2.8 中命名参数的引入,术语“按名称参数”可能会变得更加混乱。
  • 参数可以按名称、按值或按引用传递。这是计算机科学标准。 按名称 表示参数的“名称”在接收它的函数中被有效替换——如果它是一个完整的表达式,那么整个表达式在接收参数的函数中被替换。 按值 表示将参数的值复制并传递给接收函数。 通过引用意味着对参数的引用被传递给接收函数——这使得它能够改变调用函数中的值。
  • Java通过值传递所有原语,所有对象作为值引用——即复制对象的引用并传递,所以可以改变对象本身,但不能改变参数(变量) 在原始函数中。 Scala 紧随其后,但名称参数除外。
【解决方案2】:

由于我的记忆力很差,而且答案没有提供一个示例,如何实际声明一个按名称参数生成的函数采用一个或多个参数,所以我想出了这个:

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() )
    }

}

【讨论】:

    猜你喜欢
    • 2016-10-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多