JavaRush /Courses /Kotlin SELF /Escaping and string templates: the characters \, " and $

Escaping and string templates: the characters \, " and $

Kotlin SELF
Level 9, Lesson 1
Available

1. Introduction

If you’re just starting to program, strings seem as harmless as it gets: well, text is text. But the compiler disagrees. To it, a string is a piece of source code that must be parsed according to rules. And some characters inside a string literal have special meaning: they either end the string or switch on a “special mode”. Escaping is a way to tell the compiler: “Yes, I know this is a special character, but right now it must become ordinary text.”

Imagine you’re writing a letter, but every time the word STOP appears it suddenly means “finish the letter and send it”. At some point you’ll want to write the word STOP as a word, not as a command. Escaping is your “quote mode”: it turns a “command” back into “ink on paper”.

Regular string "..." and special characters

In Kotlin, a regular string is written in double quotes:

val s = "Hello!"

From that point on, the compiler closely watches two things.

First, a double quote " inside the string ends the string. That is, if you just write:

val s = "He said: "Hello""

the compiler will honestly try to understand why the string suddenly ended after He said: , and why some kind of chaos follows.

Second, a backslash \ inside the string is not “just a slash character”, but a signal: “An escape sequence is coming.” That is, \n is not two characters \ and n, but one special “newline” character.

These two rules (a quote ends a string; a backslash starts an escape) are the main sources of “why doesn’t it compile?” in strings. And these are exactly what we’ll tame today.

2. Escape sequences: \n and \t

When you write \n inside a regular string, Kotlin creates a single character that means a line break (Enter). So output continues on a new line.

When you write \t, that’s the tab character—“tab”, which visually often looks like several spaces, but in reality it’s a separate control character. It’s useful when you want to roughly align text columns without complex formatting.

Let’s look at this in a mini example. We’ll keep developing one more learning console application: NoteKeeper—a small note pad. It’s not “smart” yet, but it’s honest.

fun main() {
    println("NoteKeeper\n1) Add a note\n2) Show all\n0) Exit")
}

Here \n makes the text multi-line. The output will look roughly like this:

NoteKeeper
1) Add a note
2) Show all
0) Exit

Now an example with a tab:

fun main() {
    println("Command\tDescription")
    println("add\tAdd a note")
    println("list\tShow all")
}

I wrote the output of this program next to it in comments:

fun main() {
    println("Command\tDescription")      // Command    Description
    println("add\tAdd a note")          // add        Add a note
    println("list\tShow all")           // list       Show all
}

For now, don’t try to turn \t into an “Excel-grade perfect table”. It’s a simple tool. If strings have different lengths, tabs don’t always produce perfectly aligned columns—but for learning menus and hints it’s totally fine.

3. Escaping quotes and the backslash

Now let’s take the two most popular “string breakers”.

How to print a double quote " inside a string

So that a quote doesn’t end the string, you must escape it: \".

fun main() {
    val quote = "He said: \"Hello\""
    println(quote) // He said: "Hello"
}

So \" inside a string means “insert a regular quote character into the text”.

This is especially useful when you want to nicely show user input or data in a report. For example: Note "Buy milk" added.

How to print a backslash \ inside a string

To get a single \ character inside a regular string, you need to write two: \\.

fun main() {
    val path = "C:\\Users\\alex\\notes.txt"
    println(path) // C:\Users\alex\notes.txt
}

Why? Because the first \ says “I’m starting an escape sequence”, and the second clarifies “specifically—I need a backslash character”.

And this is where the classic trap lives:

fun main() {
    val bad = "C:\new\test"
    println(bad)
}

At a glance it’s a “path”. But in reality Kotlin will see \n (newline) and \t (tab). So the string turns into unexpected mush, and you’ll stare at the output for a long time thinking “I just wanted to save a file”. Kotlin isn’t to blame—the backslash is special in strings.

4. String templates and the $ character

String templates in Kotlin are a way to insert values directly into a string without concatenation using +: $a for a name and ${...} for an expression.

Substituting variables and expressions

The simplest option is to substitute a variable:

fun main() {
    val title = "Plans for the day"
    println("Note: $title") // Note: Plans for the day
}

If you need to insert an expression rather than just a name, use curly braces:

fun main() {
    val a = 7
    val b = 5
    println("$a + $b = ${a + b}") // 7 + 5 = 12
}

Read it like this: “insert a, insert b, then compute a + b and insert the result”. The practical rule is simple: a name—without braces; an expression—in ${...}.

Trap: why $a + b is not the same as ${a + b}

A very typical beginner mistake: you want to print a sum, you write it “like a human”, and you get something else.

fun main() {
    val a = 2
    val b = 3
    println("$a + $b = $a + $b") // 2 + 3 = 2 + 3
}

From Kotlin’s point of view, this is perfectly logical: $a is substituting variable a, then comes the text + , then substitution $b, then the text = , then again $a, then text + , then $b. There was no sum here.

And now the correct version:

fun main() {
    val a = 2
    val b = 3
    println("$a + $b = ${a + b}") // 2 + 3 = 5
}

Curly braces enable “expression mode”. And this rule is worth memorizing as a reflex: as soon as there’s at least one operator (+, -, *, /), a function call, or a property access inside the substitution—you always need ${...}.

How to print $ as plain text

$ in Kotlin starts a string template. So trying to write:

val s = "Price: $"

will end with a compilation error: Kotlin expects a name after $ ($price) or { (${price}), but you just ended the string.

The correct way to print the $ sign as text is to escape it: "\$".

fun main() {
    val price = 19
    println("Price: \$${price}") // Price: $19
}

Let’s break it down character by character once, so it’s clear.

At the start, \$ prints a literal dollar sign. Then ${...} substitutes the number. The final result is $19.

In NoteKeeper this will be useful, for example, if we want to store expense notes (for now, just as text). Suppose a note is: Coffee $4. Then output might look like this:

fun main() {
    val item = "Coffee"
    val cost = 4
    println("Purchase: $item, price: \$${cost}") // Purchase: Coffee, price: $4
}

Sometimes a “super-smart string” is worse than two val

At this point there’s often a temptation: “Oh, templates can do expressions! Let’s cram everything in there!” And you end up with a string that looks like a spell in an ancient language.

Technically, Kotlin allows fairly complex expressions inside ${...}. But good style is: compute first, then insert. This makes code more readable, and it’s easier for you (and your future colleagues, and your future “me a week later”) to debug.

Compare two variants. The overly clever one:

fun main() {
    val a = 10
    val b = 3
    println("Result: ${a / b}, remainder: ${a % b}") // Result: 3, remainder: 1
}

This is still tolerable, but already on the edge. The second variant is much better:

fun main() {
    val a = 10
    val b = 3
    val div = a / b
    val rem = a % b

    println("Result: $div, remainder: $rem") // Result: 3, remainder: 1
}

Here the names gain meaning: div and rem. And it’s much easier to read.

Kotlin encourages string templates instead of concatenation. But “use templates” is not the same as “hide all logic inside templates”. Templates are about output; calculations are better done separately.

6. NoteKeeper: messages and menu

Now we’ll do a small (but very real-life) upgrade to our console NoteKeeper: we’ll learn to print clear messages that include quotes, line breaks, and templates.

Let’s imagine we already have a fixed-size array of notes, and we add one note and then print a confirmation.

fun main() {
    val notes = Array(5) { "" }
    var count = 0

    val newNote = "Buy milk"
    notes[count] = newNote
    count++

    println("Added: \"$newNote\" (total notes: $count)")
    // Added: "Buy milk" (total notes: 1)
}

Here we displayed the note in quotes using \" so the user can see the text boundaries. We used $newNote and $count so we wouldn’t have to glue strings together with +. And we got a readable string where it’s easy to see what exactly gets printed.

Now let’s make a simple menu as a single string with \n so we can print it with one command:

fun main() {
    val menu =
        "NoteKeeper\n" +
        "1) Add a note\n" +
        "2) Show all\n" +
        "0) Exit"

    println(menu)
}

Yes, there is + here. For now we’re using it intentionally: multi-line raw strings """...""" will be in the next lecture, and there you’ll see a much nicer way. For now, your goal is to understand what \n is and why it works.

7. Common mistakes with escaping and string templates

Mistake #1: forgetting that \ in a regular string is a special character.
Most often this comes up with Windows paths. The string "C:\new\test" unexpectedly turns into “C:”, then a newline because of \n, then a tab because of \t, and then some other weird characters. If you need a literal backslash, write \\.

Mistake #2: trying to insert an expression without ${...}.
"$a + $b = $a + $b" looks plausible, but it’s just text. To compute the sum, you need the expression template: "${a + b}". This rule follows from the string template model in Kotlin itself: a name is $a, an expression is ${...}.

Mistake #3: trying to print $ as a normal character and getting a compilation error.
The string "Price: $" doesn’t “print a dollar”—it breaks, because $ starts a template. To print a dollar sign, use "\$", and if you need a number next to it—combine \$ and ${price} like in "\$${price}".

Mistake #4: overloading a single string with computations and then being unable to debug it.
When there are too many ${...} inside "...", especially with operators and complex expressions, the string turns into a puzzle. It’s much calmer to compute into separate val first, and then print using simple $name.

Mistake #5: confusing the effect of println and \n.
println() already adds a newline at the end. If you write println("Hello\n"), you’ll get an extra blank line (or an extra line break) where you didn’t expect it. It’s not a tragedy, but in menus and reports it quickly leads to “why did everything shift?”.

1
Task
Kotlin SELF, level 9, lesson 1
Locked
Terminal Menu
Terminal Menu
1
Task
Kotlin SELF, level 9, lesson 1
Locked
Command help
Command help
1
Task
Kotlin SELF, level 9, lesson 1
Locked
Note receipt
Note receipt
1
Task
Kotlin SELF, level 9, lesson 1
Locked
File path
File path
Comments
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION