문제

우리는 최근에 코드를 프로파일 링하고 있으며 몇 가지 성가신 핫스팟을 발견했습니다. 그들은 형태입니다

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

이러한 어설 션 중 일부는 문자열 동의가 추가되기 시작하는 엄청난 양의 코드라고 할 수 있기 때문입니다. assert 다음과 같이 정의됩니다.

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

왜 다음과 같이 정의되지 않습니까?

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

그렇게하면 게으름하게 평가할 것입니다. 그것이 그렇게 정의되지 않았다는 것을 감안할 때, 게으르게 평가되는 메시지 매개 변수로 Assert를 호출하는 인라인 방법이 있습니까?

감사

도움이 되었습니까?

해결책

게으른 평가에는 생성 된 기능 객체에 대한 오버 헤드도 있습니다. 메시지 객체가 이미 완전히 구성된 경우 (정적 메시지)이 오버 헤드는 불필요합니다.

유스 케이스에 적합한 방법은 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 })

다른 팁

이름이 지정되어 있습니다. 1 년 전에 변경했습니다.

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

Thomas의 대답은 훌륭하지만 마지막 답변에 대한 아이디어가 마음에 들지만 읽을 수없는 것을 싫어하는 경우를 대비하여 다음을 해결할 수 있습니다.

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