2014-12-08 4 views
0

Внутри тела функции, которая имеет параметр «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?

EDIT: Разъяснение - мой код выше работ, но я просто спрашиваю, есть ли лучший способ «задержать оценку» параметра 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 
} 
+0

Не уверен, что я понимаю ваш вопрос, он очень смущен. Что такое определение 'timeit'? В Scala определения функций определяют, передается ли параметр по значению или по имени, если вы хотите вызывать 'timeit' с' f', не оценивая его, тогда вам нужно убедиться, что 'timeit' принимает этот параметр по имени. – vptheron

+0

Если ваш 'timeit' принимает параметр by-name, тогда он не будет работать как таковой? (Я считаю, что параметры по-имени запутаны и предпочитают использовать явно ленивый тип типа '() => Int', который всегда работает так, как вы ожидаете) – lmm

+0

@vptheron: я добавил код для' timeit' к сообщению - и пусть я уточняю: мой код работает, я просто хочу удостовериться, что я не пропускаю более синтаксис для «задержки оценки» параметра 'f' при вызове' timeit'. – ttsiodras

ответ

0

Видимо, единственное, что мне не хватало, что я могу передать f внутри скобок (спасибо, @vptheron).

common.utils.timeit(repeat = 20, assertResult = Some(148848))(f) 
Смежные вопросы