scala中原始字符串插值和三重引号之间的区别是什么

时间:2014-09-02 21:47:05

标签: string scala string-interpolation

Scala使用三重引号字符串"""String\nString"""来在字符串中使用特殊字符而不进行转义。 Scala 2.10还为了同样的目的添加了raw"String\nString"

raw""""""""的工作方式有何不同?他们可以为同一个字符串产生不同的输出吗?

2 个答案:

答案 0 :(得分:56)

查看默认插值器的源代码(在此处找到: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”,世界“!\ n”,其中\ n未转换为换行符,以及围绕单词世界的引号。

答案 1 :(得分:22)

令人惊讶的是,即使使用三引号,使用s-interpolator也会重新开启:

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

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

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

s-interpolator不知道它正在处理原本是三引号的字符串部分。因此:

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
相关问题