How do normal string literals work?
In Kotlin, normal string literals are enclosed in pairs of single double quotes: "like this"
. Characters like line break, backslash \
and double quotes "
work as special syntax and can't enter the string verbatim, so in order to include them we often have to write escape sequences: \n
, \\
, \"
.
How do raw string literals work?
In Kotlin, raw string literals are enclosed in pairs of triple double quotes: """like this"""
. Raw string literals don't have escape sequences, instead they allow you to verbatim write characters that would otherwise work as special syntax. Oh, except for dollar sign syntax for string interpolation — more on that later.
When to consider raw string literals?
Raw string literals can be very convenient for writing formatted output that has line breaks, backslashes and quote marks, for example, text file data output or interactive text menus. In fact, any text could be sophisticated enough that escaping each special character would be detrimental to its readability.
Example:
print("""Hello, $username, welcome to "File Shredder 3000"!
Please input the "path\to\file_or_directory" that you wish to shred:
C:\Users\$username\""")
When to always use raw string literals?
It's worth noting that from time to time we have to write code in RegEx, SQL, JavaScript, HTML, or any other language — that lives inside string literals within our Kotlin code. This is where raw strings really shine and are absolutely a necessity — language injections. Here raw strings provide a way to write inner syntax without being bothered by outer syntax. Even if your language injection doesn't contain special characters, it might be a good idea to write them as raw string literals in advance, just in case such characters will be added in future changes, to avoid syntactic and semantic errors in injected code.
Example*:
val textNodeRe = Regex("""(?:^|>)(.*?)(?:<|$)""", setOf(MULTILINE, DOT_MATCHES_ALL))
val openingTagRe = Regex("""<(\w+).*?>""")
val closingTagRe = Regex("""</(\w+).*?>""")
val openingAnchorTagRe = Regex("""<a.*?href="(.+?)".*?>""")
val closingAnchorTagRe = Regex("""</(a).*?>""")
What's the catch?
There is a catch with raw string literals. They still support string interpolation using the dollar sign $
syntax, and since raw string literals don't have escape sequences, writing a word prefixed by a dollar sign requires a verbose and hacky workaround: """${"$"}like this"""
. And of course, being the boundary of the raw string literal, the triple double quotes """
also require similar treatment to be included: """${"\"\"\""}"""
.
Do we use raw strings only for simplicity and easy implementation?
generally yes. – Phyllome