Start learning free

LESSON 197 OF 415 · STRINGS

Introduction to Strings in Swift: Characters, Indexes and Value Semantics

Reading Read the full explanation

Watch the lesson

Next lesson

SWIFT · STRINGS

Intro To Strings in Swift, explained

What a string is in Swift

A String is an ordered collection of Character values. You write one with double quotes, and Swift infers the type:

let greeting = "Hello"
var name = "Andy"
name += "!"
print(greeting, name, name.count)
Hello Andy! 5

The chapter that starts here uses strings in interview-style problems: reversing, comparing and splitting them. Swift's strings behave differently from those in many other languages, so it helps to know the three ideas below before you start.

Idea 1: a Character is what a reader sees as one letter

A Character is a single visible character, even when Unicode stores it as several pieces. The letter "e" followed by a combining accent is one Character made of two Unicode scalars and three bytes in UTF-8:

let e = "e\u{301}"
print(e.count, e.unicodeScalars.count, e.utf8.count)
1 2 3

This is why count counts characters, and why finding the length of a string means walking through it: characters have different sizes in memory, so Swift cannot jump to the n-th one directly.

Idea 2: no integer subscripts

Because of that, str[2] is a compile error. To reach a position you build a String.Index:

let s = "Hello"
let idx = s.index(s.startIndex, offsetBy: 2)
print(s[idx])
l

An offset past the end stops the program with an "index out of bounds" error. When a problem needs many positional reads or writes, convert the string first with Array(s). An array of characters can be indexed with plain integers and changed in place, and String(chars) turns it back into a string.

Slicing a string gives a Substring, a view into the original text. Wrap it in String(...) to get an independent string:

let str = "JavaScript"
let start = str.index(str.startIndex, offsetBy: 2)
let end = str.index(str.startIndex, offsetBy: 6)
let sub = str[start..<end]
print(sub, String(sub))
vaSc vaSc

Idea 3: strings are values

A String is a value type: assigning it to another variable copies it, and changing one copy never affects the other. let makes a string constant, var makes it changeable. There is no way to modify one character of a string in place, so "changing" a character means building a new string. Building a string character by character with += is fine, but prepending to the front each time copies the whole string again, so a loop that does it takes O(n²) time.

Two more details come up in the problems:

  • + joins two String values, but it does not accept a Character. Write String(ch) + rest. The compiler reports that it cannot convert a value of type Character to the expected argument type String.
  • Comparing strings with == compares their contents, so "apple" == "apple" is true.

Everyday operations

You will meet a few members of String again and again. All of these were run on let s = "Hello":

print(s.uppercased(), s.hasPrefix("He"), s.contains("ell"), s.isEmpty)
print(s.prefix(2), s.suffix(3), s.dropLast())
let name = "Ada"
print("Hi \(name), \(3 * 2)")
HELLO true true false
He llo Hell
Hi Ada, 6

The last line uses string interpolation: \(expression) inside a literal inserts the value of the expression. Iterating is direct as well. for ch in s visits each Character in order, and s.reversed() gives the characters back to front, which String(...) turns into a string again.

Splitting and joining are the other pair to remember: split(separator: " ") breaks a string into an array of Substring values, and joined(separator:) on an array of strings builds one string from many pieces, which is cheaper than appending in a long chain.

Key takeaways

  • A String is a collection of Character values, and count counts characters.
  • Index with String.Index or convert to Array(s) when you need integer positions.
  • Slices are Substring values; wrap them in String(...) to keep them.
  • Strings are values, so any change builds a new string. Plan for that when a loop edits one.
Keep going with SwiftAbout 340 step-by-step lessons, from your first line of code to coding interviews. Free to start.
Start learning free