1. Overview
String templating is a nice feature in Kotlin. It allows us to embed expressions or variables into a literal string, and Kotlin evaluates them, such as “The value is: $variable” and “42 x 42 = ${42 * 42}”.
Another member of Kotlin’s string family is the raw string. We can easily put multi-line text in a raw string. Further, we don’t have to escape special characters in a raw string. This feature is pretty convenient when we define regex patterns or file paths as raw strings. Also, raw strings support string templates.
However, sometimes, we do want a string template pattern to not be evaluated. For example, this could be when we want to have a literal dollar sign ($) followed by some text in a string.
So, in this tutorial, we’ll discuss how to turn string templates into literal strings.
2. Not All “$xxx”s Are String Templates
Kotlin’s string template begins with a dollar sign. So, escaping the dollar signs is the key to telling Kotlin to represent it as literal strings.
However, not all ‘*$*‘s lead string templates. Let’s see some examples:
val myStr1 = "The new iPhone's price is from $999"
val myStr2 = "The new iPhone's price is from $ 999"
val myStr3 = "The new iPhone's price is from 999$"
As we’ve seen, the ‘$’ signs in the three strings above are all literal ‘$’ characters, although we don’t do anything special to them. This is because, in this case, the character sequences following ‘$’s aren’t valid Kotlin variable names.
However, if it’s not the case, we have to do something to the dollar characters to disable their special meanings.
Next, let’s see them in action.
3. Escaping the Dollar Character
First of all, let’s put our expected string in a text file:
$ cat src/test/resources/test-data/literalStr.txt
In shell script, ${ parameter } is called parameter substitution.
As the cat output shows, we have “*${ parameter }*” as the literal string in the file. Simultaneously, this is a valid Kotlin string template pattern. Therefore, we need to escape the dollar sign.
Escaping a character in Kotlin is the same as Java. *We add a backslash (\*) before the target character.
As our application is a Maven project, we can use the getResource() function to read the expected string from the file above and store it in a Kotlin variable:
val expectedStr = this.javaClass.getResource("/test-data/literalStr.txt")?.readText() ?: IllegalStateException()
So next, let’s create a unit test to see if escaping ‘*$*‘ gives us the expected literal string:
val myStr = "In shell script, \${ parameter } is called parameter substitution."
assertEquals(expectedStr, myStr)
If we run the test, it passes. Therefore, *‘\$‘ can turn a string template into a literal string*.
However, we cannot escape a character in Kotlin raw strings. This is because Kotlin’s raw string doesn’t support backslash escaping before any symbol:
val myRawStr = """In shell script, \${ parameter } is called parameter substitution."""
If we compile the line above, the Kotlin compiler complains:
Kotlin: Unresolved reference: parameter
Therefore, if we want to apply this “escaping” approach to raw strings, we need to put the escaped part in a variable, for example:
val myVar = "\${ parameter }"
val myRawStr = """In shell script, $myVar is called parameter substitution."""
assertEquals(expectedStr, myRawStr)
The test above passes, although adding an extra variable only for the escaped string looks a bit convoluted.
So next, let’s see another way to turn string templates into literal strings.
4. Using Kotlin Identifiers
Apart from escaping ‘*$*‘, we can use the identifier “*${‘$’}*” to represent a literal dollar character. Both single-line strings and raw strings allow identifiers.
Next, let’s create a test to see how it works:
val mySingleStr = "In shell script, ${'$'}{ parameter } is called parameter substitution."
assertEquals(expectedStr, mySingleStr)
val myRawStr = """In shell script, ${'$'}{ parameter } is called parameter substitution."""
assertEquals(expectedStr, myRawStr)
The test passes if we give it a run. As we can see, we can directly use the ${‘$’} identifier in the raw string.
5. Conclusion
In this article, we’ve learned two ways to turn Kotlin string templates into literal strings: escaping the character (“*\$“) and using the (“${‘$’}*“) identifier.
As always, the full source code used in the article can be found over on GitHub.