Strings & String Templates
Reviewed & published by Brayan K
A string is a sequence of characters, and a string template lets you embed values directly inside text using $variable or $${expression} instead of clumsy concatenation.
Part of the free Kotlin course at LearnCodingFast — hands-on lessons with worked examples and the output they print, plus practice exercises and a quick quiz.
You'll also meet triple-quoted multiline strings and the handful of string methods you'll reach for every day.
What You'll Learn in This Lesson
- String templates with $var and ${expr}
- Escaping a literal dollar sign
- Triple-quoted raw strings with trimIndent()
- Everyday methods: length, uppercase, trim, split, replace
- Accessing characters by index
- Why strings are immutable
1️⃣ String Templates
Inside a normal "..." string, $name drops in a variable's value. For anything more complex — a calculation, a property, a method call — wrap it in $${ }. This is cleaner and faster to read than joining strings with +.
fun main() {
val name = "Ada"
val year = 1815
// $var inserts a simple variable:
println("Hello, $name!") // -> Hello, Ada!
// ${'${expr}'} inserts a whole expression:
println("Born ${2025 - year} years ago") // -> Born 210 years ago
// Access properties inside ${'${...}'} too:
println("Name has ${name.length} letters") // -> Name has 3 letters
// To print a literal dollar sign, escape it: \$
println("Price: \$5") // -> Price: $5
}2️⃣ Multiline Raw Strings
Triple quotes """...""" create a raw string: newlines are preserved and backslashes are literal, so there's nothing to escape. The one wrinkle is leading indentation from your source — .trimIndent() strips the common left margin so the text prints flush.
fun main() {
// Triple quotes make a RAW multiline string —
// no need to escape, and newlines are kept.
val poem = """
Roses are red,
Violets are blue,
Kotlin is concise,
And so are you.
""".trimIndent()
println(poem)
}3️⃣ Common Methods & Character Access
Strings come with a rich toolbox. Every method returns a new string — the original never changes — which is why you can safely chain calls like s.trim().uppercase().
fun main() {
val s = " Kotlin Rocks "
println(s.trim()) // -> Kotlin Rocks
println(s.trim().uppercase()) // -> KOTLIN ROCKS
println(s.trim().lowercase()) // -> kotlin rocks
println(s.length) // -> 16 (spaces counted!)
println("Kotlin".substring(0, 3)) // -> Kot
println("a,b,c".split(",")) // -> [a, b, c]
println("yes".replace("yes", "no")) // -> no
}You can also reach into individual characters with [ ] indexing, just like a list:
fun main() {
val word = "Kotlin"
// Index a single character with [ ] (0-based):
println(word[0]) // -> K
println(word[word.length - 1]) // -> n
// first() and last() read nicer:
println(word.first()) // -> K
println(word.last()) // -> n
// Loop over every character:
for (c in "abc") print("$c-") // -> a-b-c-
println()
}Your turn. Fill in the ___ blanks, then run and compare.
// 🎯 YOUR TURN — replace each ___ then run main()
fun main() {
val city = "Paris"
// 1) Use a string template to greet the city
println("Welcome to $___") // 👉 $city
// 2) Print the number of letters using ${'${...}'}
println("It has ${city.___} letters") // 👉 city.length
// ✅ Expected:
// Welcome to Paris
// It has 5 letters
}Mini-Challenge: Name Formatter
Split a lowercase full name and print each part capitalized. Combine split, indexing, and templates.
// 🎯 MINI-CHALLENGE: a name formatter.
// Save as Formatter.kt and run main().
//
// Given a full name "ada lovelace":
// 1. Split it on the space into two parts.
// 2. Print "First: Ada" and "Last: Lovelace"
// with each part's first letter uppercased.
//
// Hint: split(" "), then replaceFirstChar { it.uppercase() }.
//
// ✅ Expected output:
// First: Ada
// Last: Lovelace
fun main() {
val fullName = "ada lovelace"
// your code here
}Common Errors (and the fix)
- ❌ "Total: $price.amount" only inserts price. ✅ Wrap property access: $${price.amount}.
- ❌ Expecting s.uppercase() to change s. ✅ Strings are immutable; capture the result: val u = s.uppercase().
- ❌ A multiline string printing with stray indentation. ✅ Append .trimIndent().
- ❌ word[word.length] throws — that index is out of bounds. ✅ The last valid index is word.length - 1 (or use last()).
Pro Tips
- 💡 Prefer templates over +: "Hi $name" beats "Hi " + name for clarity.
- 💡 Chain freely: because each method returns a new string, s.trim().lowercase().replace("-", " ") is fine.
- 💡 Use isEmpty() / isBlank() to test for empty or whitespace-only strings instead of comparing lengths.
📋 Quick Reference — Strings
| Task | Kotlin Syntax |
|---|---|
| Insert a variable | "Hi $name" |
| Insert an expression | "Len $${s.length}" |
| Multiline string | """...""".trimIndent() |
| Length | s.length |
| Change case | s.uppercase() |
| Split on a char | s.split(",") |
| Index a char | s[0] |
🎉 Lesson Complete!
- ✅ $var inserts a variable; $${expr} inserts any expression
- ✅ Escape a literal dollar sign as \$
- ✅ Triple quotes make raw multiline strings; trimIndent() cleans the margin
- ✅ Methods like trim, uppercase, split return new strings
- ✅ Index characters with s[i]; strings are immutable
Practice quiz
Inside a normal double-quoted string, what does $name do?
- Inserts the value of the variable name
- Prints the literal text $name
- Throws a compile error
- Declares a new variable
Answer: Inserts the value of the variable name. $name is a string template that splices the variable's value into the text.
Which syntax inserts a whole expression like a method call into a template?
- $(expr)
- ${expr}
- $<expr>
- $$expr
Answer: ${expr}. Wrap any expression in curly braces: "${name.length}".
How do you print a literal dollar sign in a regular double-quoted string?
- $$
- Use %d
- Escape it as \$
- It is impossible
Answer: Escape it as \$. Escape the dollar sign with a backslash: "Price: \$5".
What do triple quotes """...""" create?
- A char literal
- A mutable string
- A comment block
- A raw multiline string
Answer: A raw multiline string. Triple-quoted strings keep newlines and treat backslashes literally.
What does trimIndent() do to a triple-quoted string?
- Removes the common leading whitespace from every line
- Deletes all whitespace
- Reverses the string
- Converts it to uppercase
Answer: Removes the common leading whitespace from every line. trimIndent() strips the shared left margin so text prints flush.
Are Kotlin strings mutable?
- Yes, methods change them in place
- No, they are immutable and methods return new strings
- Only var strings are mutable
- Only inside a class
Answer: No, they are immutable and methods return new strings. Strings are immutable; uppercase(), trim(), etc. return brand-new strings.
What does " hi ".trim() return?
- " hi "
- "HI"
- "hi"
- An error
Answer: "hi". trim() removes leading and trailing whitespace, leaving "hi".
How do you read the first character of the String word?
- word.char(0)
- word.get(1)
- word.head
- word[0]
Answer: word[0]. Index characters with [ ] (0-based), so word[0] is the first char.
What is the value of "Kotlin".length?
- 5
- 6
- 7
- 0
Answer: 6. The string "Kotlin" has six characters.
What does "a,b,c".split(",") produce?
- The string "abc"
- A list [a, b, c]
- The number 3
- A single char ','
Answer: A list [a, b, c]. split(",") breaks the text into a list of substrings: [a, b, c].
Continue this course
- Previous: Ranges & Progressions
- Next: Arrays — arrayOf, IntArray, indexing and iterating — and how arrays differ from List
- Quick reference: Kotlin cheat sheet
Frequently asked questions
What is the difference between $var and ${...} in a template?
Inside a double-quoted string, $name inserts the value of a single variable directly. When you need more than a bare variable — a property access, a method call, or arithmetic — you wrap the whole expression in curly braces, like ${name.length} or ${2 + 2}. Both are evaluated and their string form is spliced into the result, which is far cleaner than gluing strings together with the + operator.
How do I print a literal dollar sign in a string?
Because $ begins a template, you escape it with a backslash: "Price: \$5" prints Price: $5. In a triple-quoted raw string, where backslashes are not escape characters, the idiomatic trick is to embed the dollar sign as an expression: ${'$'}. Both approaches let the dollar sign appear literally instead of starting an interpolation.
Why use triple-quoted strings, and what does trimIndent() do?
Triple-quoted (raw) strings let you write text across multiple lines without escaping quotes or newlines, which is ideal for JSON, SQL, or formatted output. The catch is that the leading indentation in your source becomes part of the string. Calling trimIndent() removes the common leading whitespace from every line, so the text lines up with your code while printing cleanly.
Are Kotlin strings mutable? What does a method like uppercase() return?
Kotlin strings are immutable — methods never change the original. uppercase(), trim(), replace(), and friends all return a brand-new string, leaving the source untouched. That is why you chain them, as in s.trim().uppercase(): each call hands its result to the next. If you assign the result back to a val you simply keep the new value.