The Magic of Strings: Why Formatting in Kotlin is an Art
\n\nImagine: you are writing an app for tracking sports workouts. You need to display a message: "Hello, Alexey! Your time: 42.5 km in 2:15:07. Best result is 3.2% better.". If you assemble such a string using concatenation in the Java style, the code will turn into a mess of plus signs and quotes. String formatting in Kotlin solves this problem elegantly and powerfully.
\n\nIn this article, we will cover 5 approaches to Kotlin String formatting. You will learn when to use interpolation, when to use the good old String.format(), and when to use advanced templates. Let's go!
1. String Interpolation: The Bread and Butter of Kotlin
\n\nThe most popular and simple technique is string interpolation in Kotlin. It is built right into the language: use the dollar sign $ to insert a variable and ${} for expressions.
val name = "Anna"\nval age = 28\nval message = "My name is $name, I am $age years old."\nprintln(message) // My name is Anna, I am 28 years old.\n\n// Expressions with curly braces\nval price = 49.99\nval discount = 0.2\nval finalPrice = "Price with discount: ${price * (1 - discount)} rub."\nprintln(finalPrice) // Price with discount: 39.992 rub.\n\nPros: readability, speed, no extra calls. Cons: no control over number formatting (e.g., number of decimal places).
\n\nWhen to use
\n- \n
- Simple messages, logs, UI texts \n
- When precise formatting of numbers or dates is not needed \n
- Inside
println()orStringBuilder\n
2. String.format(): Java's Legacy in Kotlin
\n\nIf you need format control, String.format() in Kotlin comes to the rescue. This is a direct bridge to the Java method String.format() with the same specifiers (%s, %d, %.2f).
val pi = 3.1415926535\nval formatted = String.format("Number π with three digits: %.3f", pi)\nprintln(formatted) // Number π with three digits: 3.142\n\n// Multiple arguments\nval name = "Ivan"\nval score = 95\nval result = String.format("%s scored %d points out of 100", name, score)\nprintln(result) // Ivan scored 95 points out of 100\n\nAn important nuance: Kotlin String.format string formatting is not type-safe — if you pass the wrong type, you will get a runtime exception. For static checking, use Kotlin-specific methods (see section 5).
\n\n3. MessageFormat: When You Need Templates with Placeholders
\n\nFor complex templates with repeating arguments or localization — MessageFormat in Kotlin. It can choose word forms (singular/plural) and format dates.
\n\nimport java.text.MessageFormat\n\nval pattern = "{0} has {1} {0,choice,0#apples|1#apple|2#apples}."\nval result = MessageFormat.format(pattern, "Petya", 5)\nprintln(result) // Petya has 5 apples.\n\n// With date\nval datePattern = "Today is {0,date,long}. Time: {0,time,short}"\nval now = java.util.Date()\nprintln(MessageFormat.format(datePattern, now))\n\nWhen to choose: internationalization (i18n), complex declensions, templates with 5+ arguments. Con: verbose syntax and dependency on java.text.
4. Kotlin Extensions: Conciseness and Type Safety
\n\nThe Kotlin community loves extensions for string formatting. You can write your own custom solution or use ready-made libraries (e.g., kotlinx.string).
// Simplest extension\nfun String.format(vararg args: Any?): String {\n return String.format(this, *args)\n}\n\n// Usage\nval template = "Hello, %s! Your balance: %.2f USD"\nval msg = template.format("Maxim", 1234.5678)\nprintln(msg) // Hello, Maxim! Your balance: 1234.57 USD\n\nPros: concise syntax, type safety (if implemented correctly), easy to reuse. Cons: requires additional code or library.
\n\n5. Template Engines: For Complex Scenarios
\n\nFor large projects with complex templates (reports, emails, HTML), use template engines in Kotlin. Popular options: Kotlinx.html, Apache FreeMarker, or even Ktor templates.
\n\n// Example with Kotlinx.html (DSL)\nimport kotlinx.html.*\nimport kotlinx.html.stream.*\n\nval user = "Olga"\nval items = listOf("Laptop", "Mouse", "Keyboard")\nval html = createHTML().html {\n body {\n h1 { +"Order for $user" }\n ul {\n items.forEach { item ->\n li { +item }\n }\n }\n }\n}\nprintln(html)\n\nWhen to choose: generating HTML, XML, complex reports, server-side rendering. Pros: maximum flexibility, separation of logic and presentation. Cons: overhead, learning curve.
\n\nComparison Table: Which Method to Choose?
\n\n| Method | When to Use | Pros | Cons |
|---|---|---|---|
| Interpolation | Simple messages | Fast, readable | No format control |
| String.format() | Need number/date formatting | Familiar syntax | Not type-safe |
| MessageFormat | Localization, complex templates | Powerful, flexible | Verbose syntax |
| Extensions | Project-wide formatting | Concise, type-safe | Requires setup |
| Template Engines | Large projects, HTML | Maximum flexibility | Overhead |
Conclusion: Choose Wisely
\n\nString formatting in Kotlin offers many tools — from simple interpolation to powerful template engines. For 80% of tasks, interpolation and String.format() are sufficient. For complex applications, consider extensions or template engines.
Remember the main rule: code should be readable and maintainable. Choose the method that best suits your specific task, not the most complex one.
\n\nHappy coding with Kotlin!