A Swift Character represents a full Unicode grapheme cluster — what a person perceives as a single visible character — which can genuinely be composed of several underlying Unicode scalar values (an emoji combined with a skin-tone modifier, or a letter combined with an accent mark, both render as ONE character but are stored as multiple scalars). Because of this, String provides no integer subscript at all; navigating requires String.Index via methods like index(after:) or index(_:offsetBy:). count must walk the entire string counting grapheme clusters correctly, making it an O(n) operation rather than the O(1) most languages offer — a direct, honest consequence of Swift refusing to expose an indexing operation that would silently produce wrong results for real-world Unicode text.
Why str[0] doesn't compile
String simply has no Int-based subscript defined at all — this isn't a runtime crash waiting to happen, it's rejected before the program can even build.
let str = "Hello"
// let firstChar = str[0] // COMPILE ERROR: String has no integer subscript
let firstChar = str[str.startIndex] // this is how it's actually done
print(firstChar) // "H"String.Index: navigating correctly
index(after:) and index(_:offsetBy:) navigate by grapheme cluster, correctly handling multi-scalar characters — a manual integer increment could never safely do the same job.
let str = "Hello"
let secondIndex = str.index(after: str.startIndex)
print(str[secondIndex]) // "e"
let thirdIndex = str.index(str.startIndex, offsetBy: 2)
print(str[thirdIndex]) // "l"Why count is O(n), not O(1)
An emoji with a skin-tone modifier is genuinely ONE Character (one grapheme cluster) to Swift, even though it's built from multiple underlying Unicode scalars — count must actually walk the string to correctly identify each grapheme cluster boundary, which is precisely why it can't be a simple stored-length lookup.
let flag = "\u{1F1FA}\u{1F1F8}" // two Unicode scalars, rendering as ONE flag emoji
print(flag.count) // 1 — genuinely one Character, correctly counted, not 2