我们最近一直在剖析我们的代码,我们已经遇到一些烦人的热点。他们在形式

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

由于一些这些断言可以在称为串的concat开始加起来的倍巨大量的代码。 assert定义为:

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

为什么没有定义为:

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

这样,它会延迟计算。鉴于它没有定义的方式是有主叫与被懒惰地评估消息PARAM断言的一个内联的方法?

由于

有帮助吗?

解决方案

懒惰评价也有一些开销中创建的功能对象。如果消息对象是已经完全构造(静态信息)这个开销是不必要的。

为您的使用情况下的合适的方法将是sprintf的式:

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

只要有一个speciaized功能

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

当前PREDEF:

@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