Skip to content

Commit c8030c3

Browse files
colinleachColin LeachSleeplessByte
authored
Add Strings concept (#712)
* Add Strings concept * response to reviewer comments * note moved to admonition block * Update concepts/strings/about.md Co-authored-by: Derk-Jan Karrenbeld <[email protected]> --------- Co-authored-by: Colin Leach <[email protected]> Co-authored-by: Derk-Jan Karrenbeld <[email protected]>
1 parent 345e67d commit c8030c3

File tree

5 files changed

+275
-0
lines changed

5 files changed

+275
-0
lines changed

concepts/strings/.meta/config.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"authors": [
3+
"colinleach"
4+
],
5+
"contributors": [],
6+
"blurb": "Strings are an immutable sequence of Unicode characters."
7+
}

concepts/strings/about.md

Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
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

concepts/strings/introduction.md

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
# Introduction
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+
9+
A string is usually surrounded by double-quotes `" "`.
10+
11+
Some characters need escaping: `\'`, `\\`, plus the usual non-printing characters such as `\t` (tab) and `\n` (newline).
12+
13+
```kotlin
14+
val s = "Escape apostrophe \' and backslash \\."
15+
// Escape apostrophe ' and backslash \.
16+
```
17+
18+
Raw strings use 3 double-quotes, and can contain arbitrary text (no need for escaping).
19+
Multiline strings are also supported, including flexible handling of indents.
20+
21+
```kotlin
22+
val multi = """I'm a
23+
|multi-line
24+
|string with special characters \ \t """
25+
26+
multi.trimMargin() // delimiter defaults to | but can be specified
27+
//I'm a
28+
//multi-line
29+
//string with special characters \ \t
30+
```
31+
32+
Strings can be concatenated with `+`, but this is best limited to short and simple cases.
33+
There are other and often better options.
34+
35+
## String templates
36+
37+
This refers to what some other languages call "interpolation".
38+
39+
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.
40+
41+
```kotlin
42+
val x = 42
43+
val st = "x is $x, x squared is {x * x}"
44+
// x is 42, x squared is 1764
45+
```
46+
47+
The braces `{ }` are needed around expressions when parsing would otherwise be ambiguous.
48+
49+
In general, use of string templates is a more efficient and idiomatic way to combine strings than using `+`.
50+
51+
## String functions
52+
53+
Kotlin provides _many_ [`functions`][ref-string-functions] to manipulate strings.
54+
55+
Mostly, these are [`extensions functions`][ref-extensions] rather than members of the `String` class, though this has little effect on how we use them.
56+
57+
~~~~exercism/note
58+
Kotlin's rather complex [documentation][ref-string-functions] pages hide extension functions in the default view.
59+
Be sure to click `Members and Extensions` to expand this section.
60+
61+
[ref-string-functions]: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-string/
62+
~~~~
63+
64+
The following example shows just a small selection of what is available:
65+
66+
```kotlin
67+
val str = "Hello World!"
68+
69+
str.length // => 12 (a property, not a function)
70+
str.elementAt(6) // => W
71+
str.elementAtOrNull(20) // => null (index out of range)
72+
str.substring(6, 11) // => "World"
73+
74+
str.lowercase() // => "hello world!"
75+
str.uppercase() // => "HELLO WORLD!"
76+
77+
str.startsWith("Hel") // => true
78+
str.endsWith("xyz") // => false
79+
80+
str.toCharArray() // => [H, e, l, l, o, , W, o, r, l, d, !]
81+
"42".toInt() + 1 // => 43 (parsing; see also toFloat)
82+
```
83+
84+
85+
[ref-string]: https://kotlinlang.org/docs/strings.html
86+
[wiki-immutable]: https://en.wikipedia.org/wiki/Immutable_object
87+
[wiki-unicode]: https://en.wikipedia.org/wiki/Unicode
88+
[ref-stringbuilder]: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.text/-string-builder/
89+
[ref-extensions]: https://kotlinlang.org/docs/extensions.html#extensions.md
90+
[ref-string-functions]: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-string/

concepts/strings/links.json

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
[
2+
{
3+
"url": "https://kotlinlang.org/docs/strings.html",
4+
"description": "Kotlin string introduction"
5+
},
6+
{
7+
"url": "https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-string/",
8+
"description": "String functions"
9+
},
10+
{
11+
"url": "https://kotlinlang.org/docs/strings.html#string-templates",
12+
"description": "String Templates"
13+
}
14+
]

config.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1383,6 +1383,11 @@
13831383
"slug": "booleans",
13841384
"name": "Booleans"
13851385
},
1386+
{
1387+
"uuid": "157bbe3b-e4f5-41f7-8e0e-e2f57d526617",
1388+
"slug": "strings",
1389+
"name": "Strings"
1390+
},
13861391
{
13871392
"uuid": "168827c0-4867-449a-ad22-611c87314c48",
13881393
"slug": "conditionals",

0 commit comments

Comments
 (0)