|
| 1 | +# About Strings |
| 2 | + |
| 3 | +A [`string`][ref-string] in Kotlin is an immutable sequence of Unicode characters. |
| 4 | + |
| 5 | +[`Immutable`][wiki-immutable] means that any operation on a string must return a new string: the original string can never change. |
| 6 | + |
| 7 | +[`Unicode`][wiki-unicode] means that most of the world's writing systems can be represented, but (in contrast to older languages such as C) there is no 1:1 mapping between characters and bytes. |
| 8 | +This will be discussed further in the [`Chars`][concept-chars] Concept. |
| 9 | + |
| 10 | +A string is surrounded by double-quotes `" "`. |
| 11 | + |
| 12 | +Some characters need escaping: `\\`, plus the usual non-printing characters such as `\t` (tab) and `\n` (newline). |
| 13 | + |
| 14 | +```kotlin |
| 15 | +val s = "Escape backslash \\." |
| 16 | +// Escape backslash \. |
| 17 | +``` |
| 18 | + |
| 19 | +Raw strings use 3 double-quotes, and can contain arbitrary text (no need for escaping). |
| 20 | +Multiline strings are also supported, including flexible handling of indents. |
| 21 | + |
| 22 | +```kotlin |
| 23 | +val multi = """I'm a |
| 24 | + |multi-line |
| 25 | + |string with special characters \ \t """ |
| 26 | + |
| 27 | +multi.trimMargin() // delimiter defaults to | but can be specified |
| 28 | +//I'm a |
| 29 | +//multi-line |
| 30 | +//string with special characters \ \t |
| 31 | +``` |
| 32 | + |
| 33 | +Strings can be concatenated with `+`, but this is best limited to short and simple cases. |
| 34 | +There are other and often better options. |
| 35 | + |
| 36 | +## String templates |
| 37 | + |
| 38 | +[`Templates`][ref-templates] refers to what some other languages call "interpolation". |
| 39 | + |
| 40 | +If a string contains a dollar sign `$`, followed by an identifier, or contains braces (`{expression}`) surrounding an expression, those are substituted by respectively the value or the result of the expression. |
| 41 | + |
| 42 | +```kotlin |
| 43 | +val x = 42 |
| 44 | +val st = "x is $x, x squared is {x * x}" |
| 45 | +// x is 42, x squared is 1764 |
| 46 | +``` |
| 47 | + |
| 48 | +## String formatting |
| 49 | + |
| 50 | +On the JVM platform (only), `String.format()` allows more precise formatting than string templates, with [syntax][web-formats] similar to the (_very old!_) [`printf`][wiki-printf] functions. |
| 51 | + |
| 52 | +```kotlin |
| 53 | +String.format("%s %.3f", "π ≈", 3.14159) |
| 54 | +//π ≈ 3.142 |
| 55 | +``` |
| 56 | + |
| 57 | +~~~~exercism/advanced |
| 58 | +Kotlin can be compiled to several different targets: the Java Virtual Machine, JavaScript, native binaries for Linux, Windows, Android and Apple, plus two variants of WebAssembly. |
| 59 | +
|
| 60 | +Essentially the same code can be used for each, but different capabilities in the target platforms mean some differences in which standard library functions are supported. |
| 61 | +
|
| 62 | +Exercism currently uses the JVM for testing. |
| 63 | +~~~~ |
| 64 | + |
| 65 | +## String functions |
| 66 | + |
| 67 | +Kotlin provides _many_ [`functions`][ref-string-functions] to manipulate strings. |
| 68 | + |
| 69 | +Mostly, these are [`extensions functions`][ref-extensions] rather than members of the `String` class, though this has little effect on how we use them. |
| 70 | + |
| 71 | +~~~~exercism/note |
| 72 | +Kotlin's rather complex [documentation][ref-string-functions] pages hide extension functions in the default view. |
| 73 | +At moment of writing this, the most valuable content is hidden in a tab named `Members and Extensions`. |
| 74 | +Click it to expand this section and see all the members and extensions available on the `String` class. |
| 75 | +
|
| 76 | +[ref-string-functions]: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-string/ |
| 77 | +~~~~ |
| 78 | + |
| 79 | +The following example shows just a small selection of what is available: |
| 80 | + |
| 81 | +```kotlin |
| 82 | +val str = "Hello World!" |
| 83 | + |
| 84 | +str.length // => 12 (a property, not a function) |
| 85 | +str.elementAt(6) // => W |
| 86 | +str.elementAtOrNull(20) // => null (index out of range) |
| 87 | +str.substring(6, 11) // => "World" |
| 88 | + |
| 89 | +str.lowercase() // => "hello world!" |
| 90 | +str.uppercase() // => "HELLO WORLD!" |
| 91 | + |
| 92 | +str.startsWith("Hel") // => true |
| 93 | +str.endsWith("xyz") // => false |
| 94 | + |
| 95 | +str.toCharArray() // => [H, e, l, l, o, , W, o, r, l, d, !] |
| 96 | +"42".toInt() + 1 // => 43 (parsing; see also toFloat) |
| 97 | +``` |
| 98 | + |
| 99 | +## Building a string |
| 100 | + |
| 101 | +Sometimes a long string needs to be built up in stages, for example within a loop. |
| 102 | + |
| 103 | +Concatenating strings with `+` soon becomes neither elegant nor performant: immutability means that there is a _lot_ of copying required. |
| 104 | + |
| 105 | +Kotlin has various more efficient ways to combine multiple string: |
| 106 | + |
| 107 | +- String templates, described above. |
| 108 | +- [`joinToString()][ref-jointostring], which will be covered in the [Lists][concept-lists] Concept. |
| 109 | +- Java's [`StringBuilder`][ref-stringbuilder], which is not regarded as particularly idiomatic Kotlin. |
| 110 | +- Kotlin's [`buildString()`][ref-buildstring], which wraps `StringBuilder` in a more concise and idiomatic syntax. |
| 111 | +This takes string-building logic as a lambda argument, which will be discussed in a later Concept. |
| 112 | + |
| 113 | +In essence, a `StringBuilder` is a list-like structure, with many convenient methods. |
| 114 | +This is a small selection: |
| 115 | + |
| 116 | +- [`append()`][ref-sb-append] to add to the end. |
| 117 | +- [`insert()`][ref-sb-insert] to add at a specified position. |
| 118 | +- [`deleteAt()`][ref-sb-deleteat] and [`deleteRange()`][ref-sb-deleterange] to remove from specified position(s). |
| 119 | +- `toString()` to convert to a normal string at the end: concatenating everything in a single, performant operation. |
| 120 | + |
| 121 | +```kotlin |
| 122 | +// Available, not recommended |
| 123 | +val sb = StringBuilder() |
| 124 | +sb.append("Hello ") |
| 125 | +sb.append("World!") |
| 126 | +sb.toString() |
| 127 | +//Hello World! |
| 128 | +``` |
| 129 | + |
| 130 | +A `buildString()` example, using syntax from later Concepts: |
| 131 | + |
| 132 | +```kotlin |
| 133 | +val countDown = buildString { |
| 134 | + for (i in 5 downTo 1) { |
| 135 | + append(i) |
| 136 | + append("_") |
| 137 | + } |
| 138 | +} |
| 139 | +// countDown is "5_4_3_2_1_" |
| 140 | +``` |
| 141 | + |
| 142 | + |
| 143 | +[ref-string]: https://kotlinlang.org/docs/strings.html |
| 144 | +[wiki-immutable]: https://en.wikipedia.org/wiki/Immutable_object |
| 145 | +[wiki-unicode]: https://en.wikipedia.org/wiki/Unicode |
| 146 | +[web-formats]: https://docs.oracle.com/javase/8/docs/api/java/util/Formatter.html#summary |
| 147 | +[wiki-printf]: https://en.wikipedia.org/wiki/Printf |
| 148 | +[ref-stringbuilder]: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.text/-string-builder/ |
| 149 | +[ref-extensions]: https://kotlinlang.org/docs/extensions.html#extensions.md |
| 150 | +[ref-string-functions]: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-string/ |
| 151 | +[concept-chars]: https://exercism.org/tracks/kotlin/concepts/chars |
| 152 | +[concept-lists]: https://exercism.org/tracks/kotlin/concepts/lists |
| 153 | +[ref-templates]: https://kotlinlang.org/docs/strings.html#string-templates |
| 154 | +[ref-sb-append]: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.text/-string-builder/#9100522%2FFunctions%2F-705004581 |
| 155 | +[ref-sb-insert]: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.text/-string-builder/#-132863384%2FFunctions%2F-705004581 |
| 156 | +[ref-sb-deleteat]: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.text/-string-builder/#-386007892%2FFunctions%2F-956074838 |
| 157 | +[ref-sb-deleterange]: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.text/-string-builder/#-1622040372%2FFunctions%2F-956074838 |
| 158 | +[ref-buildstring]: https://kotlinlang.org/docs/java-to-kotlin-idioms-strings.html#build-a-string |
| 159 | +[ref-jointostring]: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.collections/join-to-string.html |
0 commit comments