web-dev-qa-db-fra.com

Quelle est la différence entre l'interpolation de chaîne brute et les guillemets triples dans scala

Scala a trois chaînes entre guillemets """String\nString""" pour utiliser des caractères spéciaux dans la chaîne sans s'échapper. Scala 2.10 a également ajouté raw"String\nString" dans le même but.

Y a-t-il une différence dans la façon dont raw"" et """""" travail? Peuvent-ils produire une sortie différente pour la même chaîne?

41
ntn

En regardant la source des interpolateurs par défaut (trouvés ici: https://github.com/scala/scala/blob/2.11.x/src/library/scala/StringContext.scala ) on dirait l'interpolateur "brut" appelle la fonction d'identité sur chaque lettre, donc ce que vous mettez est ce que vous sortez. La plus grande différence que vous trouverez est que si vous fournissez un littéral de chaîne dans votre source qui inclut le caractère de citation, l'interpolateur brut ne fonctionnera toujours pas. c'est-à-dire que vous ne pouvez pas dire

raw"this whole "thing" should be one string object"

mais tu peux dire

"""this whole "thing" should be one string object"""

Donc, vous vous demandez peut-être: "Pourquoi devrais-je me donner la peine d'utiliser l'interpolateur brut alors?" et la réponse est que l'interpolateur brut effectue toujours la substitution de variables. Alors

val helloVar = "hello"
val helloWorldString = raw"""$helloVar, "World"!\n"""

Vous donnera la chaîne "bonjour", "World"!\N "avec le\n non converti en une nouvelle ligne, et les guillemets autour du monde Word.

58
alexkrishnan

Il est surprenant que l'utilisation de l'interpolateur s active à nouveau les échappements, même lorsque vous utilisez des guillemets triples:

scala> "hi\nthere."
res5: String =
hi
there.

scala> """hi\nthere."""
res6: String = hi\nthere.

scala> s"""hi\nthere."""
res7: String =
hi
there.

L'interpolateur s ne sait pas qu'il traite des parties de chaîne qui étaient à l'origine entre guillemets triples. Par conséquent:

scala> raw"""hi\nthere."""
res8: String = hi\nthere.

Cela est important lorsque vous utilisez d'autres barres obliques inverses, telles que des expressions régulières:

scala> val n = """\d"""
n: String = \d

scala> s"$n".r
res9: scala.util.matching.Regex = \d

scala> s"\d".r
scala.StringContext$InvalidEscapeException: invalid escape character at index 0 in "\d"
  at scala.StringContext$.loop$1(StringContext.scala:231)
  at scala.StringContext$.replace$1(StringContext.scala:241)
  at scala.StringContext$.treatEscapes0(StringContext.scala:245)
  at scala.StringContext$.treatEscapes(StringContext.scala:190)
  at scala.StringContext$$anonfun$s$1.apply(StringContext.scala:94)
  at scala.StringContext$$anonfun$s$1.apply(StringContext.scala:94)
  at scala.StringContext.standardInterpolator(StringContext.scala:124)
  at scala.StringContext.s(StringContext.scala:94)
  ... 33 elided

scala> s"""\d""".r
scala.StringContext$InvalidEscapeException: invalid escape character at index 0 in "\d"
  at scala.StringContext$.loop$1(StringContext.scala:231)
  at scala.StringContext$.replace$1(StringContext.scala:241)
  at scala.StringContext$.treatEscapes0(StringContext.scala:245)
  at scala.StringContext$.treatEscapes(StringContext.scala:190)
  at scala.StringContext$$anonfun$s$1.apply(StringContext.scala:94)
  at scala.StringContext$$anonfun$s$1.apply(StringContext.scala:94)
  at scala.StringContext.standardInterpolator(StringContext.scala:124)
  at scala.StringContext.s(StringContext.scala:94)
  ... 33 elided

scala> raw"""\d$n""".r
res12: scala.util.matching.Regex = \d\d
23
som-snytt