Why can't you subscript a Swift String with an Int?
understanding Unicode-correct strings.
Characters are extended grapheme clusters of variable byte width, so integer offsets are not O(1) or meaningful; String.Index is an opaque position you advance via the collection.
What's really being asked
This probes whether you understand Unicode correctness and the cost model behind Swift strings. It separates engineers who think of strings as byte arrays from those who understand grapheme clusters and why random access is not free.
The full answer
A Swift Character is an extended grapheme cluster, a user-perceived character that may be composed of several Unicode scalars and stored as a variable number of UTF-8 bytes. The flag emoji or an accented letter formed by a base plus combining mark occupies more bytes than an ASCII letter. Because characters are not fixed width, you cannot jump to the nth character in constant time by multiplying an offset, so an integer subscript would be misleadingly slow and would invite off-by-byte bugs. Swift therefore models String as a bidirectional collection indexed by String.Index, an opaque value tied to a specific string that marks a position in storage. You get it from startIndex or endIndex and move it with index(after:), index(before:), or index(_:offsetBy:).
The mistakes people make
Claiming the restriction is an arbitrary API choice. Assuming one character is always one byte. Believing String.Index is just an Int wrapper that supports arithmetic like adding 5 directly.
What usually comes next
How do you get the fifth character safely? What is the difference between Character, Unicode.Scalar, and the UTF-8 and UTF-16 views? Why can an index from one string be invalid on another? What is the complexity of count?
A concrete example
To read the character at offset five, you write let i = str.index(str.startIndex, offsetBy: 5) then str[i]. For the string composed of a family emoji, count returns one even though its UTF-8 view holds many bytes, demonstrating why an integer subscript over bytes would not correspond to a single visible character.
Interview question
Why does indexing a Swift String by an integer like myString[5] not compile, unlike in many other languages?
- a.Integer subscripting was removed only for security reasons and may return later
- b.String.Index is just an alias for Int but Apple hid the operator
- c.Characters are variable-width grapheme clusters, so an integer offset cannot give O(1) or unambiguous accessCorrect
- d.Swift strings are immutable, so any subscript access is disallowed
Why? this is the answer
Swift Characters are extended grapheme clusters of varying byte length, so an integer offset is neither constant-time nor meaningful, which is why String.Index is opaque. Immutability is unrelated, and String.Index is not an Int alias.
Just read this? Test yourself on what you have been reading.
Read the original → docs.swift.org
- #ios
- #swift
- #string
- #unicode
- #performance
Put your scrolling time to good use
Learn one idea, try a quiz and save useful cards for revision. Tezvyn makes it easy to learn and stay current in your tech field, a few minutes at a time.
The iPhone app is on the way
We are building it. Until it lands, nothing here is held back from you: every interview card, your saved cards, streaks and the job board all work in Safari, plus hundreds of free practice quizzes of thirty questions each. Sign in and it all carries over to the app the day it arrives.
Want it as an icon? Tap Share at the bottom of Safari, then Add to Home Screen. It opens full screen and the cards you have read stay available offline.
We are hiring for this. Open roles that interview on ios — each one lists the topics its interview covers.
See open roles