将名称参数传播到函数调用

时间:2014-12-08 14:22:19

标签: scala

在具有“By-name”参数“f”的函数体内,我想调用另一个函数并在其中传递该参数。具体来说,我想在我的timeit函数中传递“代码块”:

def warmUpAndMeasure(f: =>Int) = {
  val minimumTimeTaken = common.utils.timeit(
    repeat = 20, 
    assertResult = Some(148848)) {
      f
    }
  println(s"Best execution took $minimumTimeTaken ms.")
}
warmUpAndMeasure { antFunctional.funcs.walk(1000,1000) }

从代码的最后一行开始,我调用warmUpAndMeasure在其中传递一个代码块。反过来,warmUpAndMeasure应该将该块传递给common.utils.timeit,但首先将其设置为重复(20次)调用传入的代码块,验证每次返回148848,并且最后报告,执行块的最短时间(总共20次)。

我是Scala的新手,到目前为止,我发现将f原样传递给timeit(而不是称之为!)的唯一方法 - 正如您所看到的那样上面的代码 - 是编写另一个无名代码块:{ f }。有没有其他方法可以指定我希望传递f,而不是在调用timeit时调用?

编辑:澄清 - 上面的代码有效,但我只是问是否有更好的方法来“延迟评估”参数f而不是写另一个块(就像我一样)所做的那样)。以下是我timeit的代码,供参考:

def timeit[A](repeat:Int=20, assertResult:Option[A] = None)(f: => A) = {
  val minimumTime = List.range(1,repeat+1).map {
    idx => {
      if (idx == 1)
        print("Benchmark iteration:     ")
      print("\b\b\b\b%4d" format idx)
      val startTime = System.currentTimeMillis
      val result = f
      var totalTime = System.currentTimeMillis - startTime
      assertResult match {
        case Some(value) => {
          try { assert(value == result) }
          catch { case e:AssertionError =>
            println("\nExpected:" + value + ", got:" + result) ; throw e
          }
        }
        case None => ()
      }
      totalTime
    }
  }.min
  print("\n")
  minimumTime
}

1 个答案:

答案 0 :(得分:0)

显然,我唯一遗漏的是我可以在括号内传递f(谢谢,@ vptheron)。

common.utils.timeit(repeat = 20, assertResult = Some(148848))(f)