Support for raw string literals
SE-0200, implemented in Swift 5, added support for raw string literals, which are string literals that add #
characters to their delimiters, and that partially ignore escape sequences like \n
and \\
. The above-linked Swift Evolution proposal goes into greater detail about their design, but a quick overview follows.
Overview of raw string literals
Traditional string literals interpret character sequences beginning with \
as escape sequences, but raw string literals interpret these as literal characters:
"\n" // newline
#"\n"# // backslash, n
"\\n" // backslash, n
#"\\n"# // backslash, backslash, n
"\u{2603}" // ☃
#"\u{2603}"# // backslash, u, opening brace, 2, 6, 0, 3, closing brace
"\\u{2603}" // backslash, u, opening brace, 2, 6, 0, 3, closing brace
#"\\u{2603}"# // backslash, backslash, u, opening brace, 2, 6, 0, 3, closing brace
let num = 42
"\(num)" // 42
#"\(num)"# // backslash, opening parenthesis, n, u, m, closing parenthesis
"\\(num)" // 42
#"\\(num)"# // backslash, backslash, opening parenthesis, n, u, m, closing parenthesis
You can use any number of #
characters as the delimiters of a raw string literal:
// All of the following strings are equivalent:
"good morning"
#"good morning"#
##"good morning"##
###"good morning"###
// et cetera
If you want to use an escape sequence in a raw string literal, the escape sequence includes the same number of #
characters as the delimiters:
// All of the following strings are equivalent:
"\n" // newline
#"\#n"#
##"\##n"##
// All of the following strings are equivalent:
"\u{2603}" // ☃
#"\#u{2603}"#
##"\##u{2603}"##
// All of the following strings are equivalent:
"\(num)" // 42
#"\#(num)"#
##"\##(num)"##
Note, the reason you can use any number of #
characters is to allow literal \#
sequences in a raw string literal without escaping:
// All of the following strings are equivalent:
"\\#n" // backslash, hash, n (need to escape \\ to get \)
#"\#\#n"# // (need to escape \#\ to get \ before #)
##"\#n"## // (no need to escape)
Swift also allows combining raw string literals with multiline string literals:
// All of the following strings are equivalent
let one = "good\\n\nmorning" // g, o, o, d, backslash, n, newline, m, o, r, n, i, n, g
let two = """
good\\n
morning
"""
let three = #"""
good\n
morning
"""#
The issue: swift.tmbundle doesn’t support raw string literals
As seen in some of the examples above, swift.tmbundle highlights raw string literals as if they were traditional string literals. That means that some valid sequences involving \
characters are marked as invalid, and some invalid sequences involving \
characters are only partially marked as invalid:
"\d" // invalid escape sequence \d (correctly marked)
#"\d"# // backslash, d (incorrectly marked as invalid escape sequence \d)
#"\#d"# // invalid escape sequence \#d (incorrectly marked as shorter invalid escape sequence \#)
##"\#d"## // backslash, hash, d (incorrectly marked as invalid escape sequence \#`)
##"\##d"## // invalid escape sequence \##d (incorrectly marked as shorter invalid escape sequence \#)