Вопрос

Недавно мы профилировали наш код и обнаружили несколько неприятных моментов.Они в форме

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

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

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

почему это не определяется как:

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

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

Спасибо

Это было полезно?

Решение

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

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

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

Другие советы

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

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top