assert lente Scala
-
19-09-2019 - |
Question
Nous avons notre code récemment établissons le profil et nous avons rencontré quelques points chauds ennuyeux. Ils sont sous la forme
assert(a == b, a + " is not equal to " + b)
Parce que certains d'entre eux peuvent être affirme code appelé une énorme quantité de temps la chaîne concat commence à additionner. assert
est défini comme suit:
def assert(assumption : Boolean, message : Any) = ....
pourquoi pas défini comme suit:
def assert(assumption : Boolean, message : => Any) = ....
De cette façon, il évaluerait paresseusement. Étant donné que ce n'est pas défini de cette façon est-il un moyen en ligne d'appeler affirmer avec un param de message qui est évalué paresseusement?
Merci
La solution
évaluation Lazy a aussi des frais généraux pour l'objet fonction créée. Si votre objet de message est déjà entièrement construit (un message statique) cette surcharge est inutile.
La méthode appropriée pour votre cas d'utilisation serait de style sprintf:
assert(a == b, "%s is not equal to %s", a, b)
Tant qu'il y est une fonction speciaized
assert(Boolean, String, Any, Any)
cette mise en œuvre n'a pas de frais généraux ou le coût du tableau var args
assert(Boolean, String, Any*)
pour le cas général.
La mise en œuvre toString serait évalué paresseusement, mais n'est pas lisible:
assert(a == b, new { override def toString = a + " is not equal to " + b })
Autres conseils
Il est par nom, je l'ai changé il y a un an.
http://www.scala-lang.org/node/825
Courant Predef:
@elidable(ASSERTION)
def assert(assertion: Boolean, message: => Any) {
if (!assertion)
throw new java.lang.AssertionError("assertion failed: "+ message)
}
La réponse Thomas est grande, mais juste au cas où vous aimez l'idée de la dernière réponse, mais l'aversion illisibilité, vous pouvez la contourner:
object LazyS {
def apply(f: => String): AnyRef = new {
override def toString = f
}
}
Exemple:
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
Essayez: assert( a==b, "%s is not equals to %s".format(a,b))
Le format ne doit être appelée lorsque le besoin assert la chaîne. Format est ajouté à RichString via implicite.