Медленный Scala утверждает

Мы представляли наш код недавно, и мы столкнулись с несколькими раздражающими горячими точками. Они находятся в форме

assert(a == b, a + " is not equal to " + b)

Поскольку некоторые из них утверждают, может быть в коде, названном огромной суммой времен, которые строка concat начинает складывать. assert определяется как:

def assert(assumption : Boolean, message : Any) = ....

почему не определенный как:

def assert(assumption : Boolean, message : => Any) = ....

Тем путем это оценило бы лениво. Учитывая, что это не определяется, тем путем является там встроенный способ звонить, утверждают с параметрическим усилителем сообщения, который оценен лениво?

Спасибо

12
задан skaffman 27 November 2011 в 15:27
поделиться

4 ответа

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

Подходящим методом для вашего варианта использования будет sprintf-style:

assert(a == b,  "%s is not equal to %s", a, b)

Пока существует специальная функция

assert(Boolean, String, Any, Any)

, эта реализация не имеет накладных расходов или затрат на массив var args

assert(Boolean, String, Any*)

для общего случая .

Реализация toString будет выполняться лениво, но не читается:

assert(a == b, new { override def toString =  a + " is not equal to " + b })
16
ответ дан 2 December 2019 в 07:02
поделиться

Попробуйте: assert (a == b, «% s не равно% s» .format (a, b)) Формат должен вызываться только тогда, когда для утверждения нужна строка. Формат добавляется к RichString неявно.

-2
ответ дан 2 December 2019 в 07:02
поделиться

Ответ Томаса отличный, но на тот случай, если вам нравится идея последнего ответа, но не нравится его нечитабельность, вы можете обойти это:

object LazyS {
  def apply(f: => String): AnyRef = new {
    override def toString = f
  }
}

Пример:

object KnightSpeak {
  override def toString = { println("Turned into a string") ; "Ni" }
}

scala> assert(true != false , LazyS("I say " + KnightSpeak))

scala> println( LazyS("I say " + KnightSpeak) )
Turned into a string
I say Ni
1
ответ дан 2 December 2019 в 07:02
поделиться

Это по имени, я изменил это больше года назад.

http://www.scala-lang.org/node/825

Текущий предопределение:

@elidable(ASSERTION)
def assert(assertion: Boolean, message: => Any) {
  if (!assertion)
    throw new java.lang.AssertionError("assertion failed: "+ message)
}
7
ответ дан 2 December 2019 в 07:02
поделиться
Другие вопросы по тегам:

Похожие вопросы: