Подтвердить что ты не робот

Какая разница между интерполяцией исходных строк и тройными кавычками в scala

Scala имеет тройные кавычки """String\nString""" для использования специальных символов в строке без экранирования. Scala 2.10 также добавил raw"String\nString" для этой же цели.

Есть ли разница в том, как работают raw"" и """"""? Могут ли они производить разные выходные данные для одной и той же строки?

4b9b3361

Ответ 1

Глядя на источник интерполяторов по умолчанию (здесь: https://github.com/scala/scala/blob/2.11.x/src/library/scala/StringContext.scala), похоже, что "сырой" интерполятор вызывает функцию идентификации на каждой букве, поэтому то, что вы вкладываете, - это то, что вы выбрали. Самое большое различие, которое вы обнаружите, заключается в том, что если вы предоставляете строковый литерал в своем источнике, который включает символ кавычек, сырой интерполятор все равно не будет работать. т.е. вы не можете сказать

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

но вы можете сказать

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

Итак, вам может быть интересно: "Зачем мне когда-нибудь беспокоиться об использовании исходного интерполятора?" и ответ заключается в том, что сырой интерполятор все еще выполняет переменную замену. Так

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

Дает вам строку "hello", "World"! \n ", когда \n не преобразуется в новую строку и кавычки вокруг мира слов.

Ответ 2

Удивительно, что использование s-интерполятора возвращается обратно, даже при использовании тройных кавычек:

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

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

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

s-интерполятор не знает, что он обрабатывает части строки, которые первоначально были трехкратно процитированы. Следовательно:

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

Это имеет значение, когда вы используете обратную косую черту другими способами, такими как регулярные выражения:

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