Before we get into how to use strings, we will cover why they are the way they are. For developers coming from other languages, this is a very reasonable question to ask.

We won't go into the details of Unicode, but there are several ways of viewing a piece of Unicode text in Swift. This is done by using different collections:

In addition to everyone reporting a different number of symbols in the string, you may have also noticed that they are all wrong. String itself, however, has the right answer:

This is because String is an ordered collection of Character. Character represents what we humans would consider one symbol, regardless of how many bytes it consists of.

The reason for the discrepancies is, of course, the two emojis:

Even a simple letter such as é may surprise you:

There may be several ways of representing the same symbol in Unicode, but Character still considers them to be equal:

Just like arrays, strings have indices, which refer to the position of every single character. But before we get into what the type of strings index is, we should cover what it is not: an integer.

The index type of an array is an integer. Because every element takes up the same amount of space, you can ask for the 500th element and it will multiply 500 with the byte size of an element, add the memory address of the first element, and find the element at the resulting address.

If we ask a string for the 500th character, it has to start with the first character, see how much space it takes, move past it, see how much space the next character takes, and so on, and repeat this 500 times.

On StackOverflow and other places, you will often find code examples which add a new subscript to String with an integer parameter, allowing us to do something such as this:

This is extremely inefficient. Consider what is actually happening here: the string has to process the first character, then the first and second characters, then the first, second, and third characters, and so on. For a string of merely 500 characters, it will have processed the first character 500 times, the second one 499, and so on until it has processed characters n(n+1)/2 or 125,250 times, plus 500 to find the count.

The following, however, will visit each character exactly once, and is much simpler: