Strings and interpolation

Swift · Essentials · 8 min

Text is everywhere in apps, and Swift's Unicode model explains why you can't index a string by an Int.

A String literal goes in double quotes; insert values with interpolation \(expression). Multi-line strings use triple quotes, and their indentation is stripped relative to the closing """.

Strings are value types: assigning or passing one copies it (cheaply, thanks to copy-on-write), so a function can never change your string behind your back.

A String is a collection of Characters, and each Character is an extended grapheme cluster — what a user sees as one symbol. "é" might be one or two Unicode scalars, and a flag emoji is two, but each counts as one Character. That is why count walks the string, and why you cannot write s[3]: indexing uses String.Index, obtained from s.startIndex, s.index(_:offsetBy:) or methods like firstIndex(of:).

Useful API:

  • hasPrefix, hasSuffix, contains, lowercased(), split(separator:).
  • s.isEmpty is faster and clearer than s.count == 0.
  • Slicing yields a Substring, which shares storage with the original; convert with String(sub) before storing it long-term.

For heavy byte-level work, use the utf8 view, which is fast and indexable in constant time per step.

Example

let user = "Ana"
let items = 3
print("Hi \(user), you have \(items * 2) points")  // Hi Ana, you have 6 points

let word = "café"
print(word.count)           // 4 characters
print(word.utf8.count)      // 5 bytes

let i = word.index(word.startIndex, offsetBy: 3)
print(word[i])              // é

let csv = "a,b,c"
let parts = csv.split(separator: ",")   // [Substring]
print(parts.map { String($0).uppercased() })  // ["A", "B", "C"]

let poem = """
    Roses are red
    Swift is fast
    """
print(poem.hasPrefix("Roses"))  // true

Remember

  • Interpolate with \(value)
  • Character = what a user sees; count is O(n)
  • Index with String.Index, not Int; convert Substring to String to keep it

Watch out for

  • Keeping a small Substring of a huge string alive, which keeps the whole buffer in memory.

Check yourself

  1. Why can't you write `name[2]` with an Int in Swift?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: docs.swift.org/swift-book/documentation/the-swift-programming-language/stringsandcharacters/

Builds on

Unlocks

Nothing builds on this yet.