web-dev-qa-db-ja.com

scalaの生の文字列補間と三重引用符の違いは何ですか

Scalaには、エスケープせずに文字列で特殊文字を使用するための三重引用符付き文字列"""String\nString"""があります。 Scala 2.10も同じ目的でraw"String\nString"を追加しました。

raw""""""""の動作に違いはありますか?同じ文字列に対して異なる出力を生成できますか?

41
ntn

デフォルトの補間器のソースを見る(ここにあります: 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は改行に変換されず、Wordの世界の引用符が表示されます。

58
alexkrishnan

三重引用符を使用している場合でも、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
23
som-snytt