-
19-09-2019 - |
문제
우리는 최근에 코드를 프로파일 링하고 있으며 몇 가지 성가신 핫스팟을 발견했습니다. 그들은 형태입니다
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에 추가됩니다.