Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the difference between raw string interpolation and triple quotes in scala

Scala has triple quoted strings """String\nString""" to use special characters in the string without escaping. Scala 2.10 also added raw"String\nString" for the same purpose.

Is there any difference in how raw"" and """""" work? Can they produce different output for the same string?

like image 316
ntn Avatar asked Sep 02 '14 21:09

ntn


People also ask

What is triple quotes in Scala?

Bookmark this question. Show activity on this post. Scala has triple quoted strings """String\nString""" to use special characters in the string without escaping. Scala 2.10 also added raw"String\nString" for the same purpose.

What is string interpolation in Scala?

String Interpolation refers to substitution of defined variables or expressions in a given String with respected values. String Interpolation provides an easy way to process String literals. To apply this feature of Scala, we must follow few rules: String must be defined with starting character as s / f /raw.

What is triple quoted string?

Python's triple quotes comes to the rescue by allowing strings to span multiple lines, including verbatim NEWLINEs, TABs, and any other special characters. The syntax for triple quotes consists of three consecutive single or double quotes.

What is raw in Scala?

The raw interpolator is similar to the s interpolator except that it performs no escaping of literals within the string. Here's an example processed string: Scala 2 and 3.


2 Answers

Looking at the source for the default interpolators (found here: https://github.com/scala/scala/blob/2.11.x/src/library/scala/StringContext.scala) it looks like the "raw" interpolator calls the identity function on each letter, so what you put in is what you get out. The biggest difference that you will find is that if you are providing a string literal in your source that includes the quote character, the raw interpolator still won't work. i.e. you can't say

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

but you can say

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

So you might be wondering "Why would I ever bother using the raw interpolator then?" and the answer is that the raw interpolator still performs variable substitution. So

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

Will give you the string "hello, "World"!\n" with the \n not being converted to a newline, and the quotes around the word world.

like image 125
alexkrishnan Avatar answered Sep 19 '22 12:09

alexkrishnan


It is surprising that using the s-interpolator turns escapes back on, even when using triple quotes:

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

The s-interpolator doesn't know that it's processing string parts that were originally triple-quoted. Hence:

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

This matters when you're using backslashes in other ways, such as regexes:

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 
like image 34
som-snytt Avatar answered Sep 21 '22 12:09

som-snytt