Skip to content
Lesson 4 of 19

Step 1 of 5 · Reading · ~4 min

Learn

Strings and Null Safety

Strings and String Templates

A Kotlin String is immutable: nothing you call on it changes it. By the end of this lesson you can build a line of output by dropping values and calculations straight into the text, and you know the one spelling mistake that compiles and prints nonsense.

fun main() {
    val greeting = "hello"
    val loud = greeting.toUpperCase()

    println(greeting)
    println(loud)
    println(greeting.length)
    println(greeting.contains("ell"))
}

//> hello
//> HELLO
//> 5
//> true

Every operation hands back a brand-new string and leaves the original as it was. greeting is still hello after the call; if you want the uppercase version, you have to keep the value that came back.

Naming note: Kotlin 1.5 renamed toUpperCase() and toLowerCase() to uppercase() and lowercase(). This course's grader runs Kotlin 1.3.70, where only the old names exist. Use toUpperCase() in anything you submit.

String templates

Instead of gluing strings together with +, you drop values straight into the text. A $ followed by a name inserts that value.

fun main() {
    val item = "tea"
    val qty = 3

    println("$qty x $item")
    println("Reorder: ${qty * 2} x $item")
    println("The word has ${item.length} letters")
}

//> 3 x tea
//> Reorder: 6 x tea
//> The word has 3 letters

A bare $item works for a plain name. Anything more — a calculation, a method call, a property — has to go inside braces as ${...}. Whatever is inside the braces is ordinary Kotlin, evaluated first; its result is then written into the text.

When do I need the braces?

You writeYou getWhy
"$item"teaa plain name needs no braces
"$item.length"tea.lengththe name stops at item; .length is just text
"${item.length}"3braces let the whole expression run
"$qty * 2"3 * 2no braces, so * 2 is just text
"${'$'}5.00"$5.00this is how you print a literal dollar sign

The middle rows are the ones that bite, because they are not errors. The program compiles happily and prints something that looks almost right.

✓ Correct:

println("The word has ${item.length} letters")

✗ Compiles, prints nonsense:

println("The word has $item.length letters")

Output of the wrong version:

The word has tea.length letters

A value that is inserted is never re-read, so a text that itself contains a $ is printed as it is.

Raw strings

Triple quotes hold text exactly as written: real line breaks, and no escape processing.

fun main() {
    val block = """
        line one
        line two
    """.trimIndent()

    println(block)
}

//> line one
//> line two

trimIndent() removes the shared leading whitespace, so you can indent the literal to match the code around it without those spaces ending up in the output. Raw strings still run templates, which is why a literal dollar sign inside one is written ${'$'}.

String calls you will keep reaching for

CallResult for "ship that code"
.length14
.trim()removes surrounding whitespace
.split(" ")[ship, that, code]
.substring(0, 4)ship
.replace("code", "kotlin")ship that kotlin
.isEmpty()false

Because every one of these returns a new string, they chain: line.trim().split(" ") is a perfectly ordinary thing to write.

Common mistakes

  • Braces forgotten around a calculation. "$age + 1" prints 25 + 1, not 26.
  • Braces forgotten around a property. "$name.length" prints the name followed by the text .length.
  • Typing the placeholder. Writing {name} or <name> from a description into your string prints those characters literally; only $ starts a template.
  • Discarding the result of a string call. name.trim() on its own line changes nothing; the trimmed copy has to be used.

Your exercise

Birthday Line reads a name and an age and prints one sentence that uses all three kinds of template: a plain name, a calculation and a property. The starter has already read both values. The mistakes the tests catch are the two in the table above — an age that prints as 25 + 1, and a name that prints as Alice.length.

Up nextNull SafetyStrings and Null Safety

Discussion

Ask a question, share an insight, or help someone who’s stuck.

Sign in to post a comment or reply.

Loading…