Why Is Swift’s String API So Hard?
Incidentally, I think that representing all these different concepts as a single string type is a mistake. Human-readable text, file paths, SQL statements, and others are all conceptually different, and this should be represented as different types at the language level. I think that having different conceptual kinds of strings be distinct types would eliminate a lot of bugs.
[…]
Swift’s
Stringtype takes a different approach. It has no canonical representation, and instead provides views on various representations of the string. This lets you use whichever representation makes the most sense for the task at hand.[…]
Going from an arbitrary sequence of UTF-16 code units back to a
Stringis pretty obscure.UTF16Viewhas no public initializers and few mutating functions. The solution is to use the globaltranscodefunction, which works with theUnicodeCodecTypeprotocol. There are three implementations of this protocol:UTF8,UTF16, andUTF32. Thetranscodefunction can be used to convert between them. It’s pretty gnarly, though. For the input, it takes aGeneratorTypewhich produces the input, and for the output it takes a function which is called for each unit of output. This can be used to build up a string piece by piece by converting toUTF32, then converting eachUTF-32code unit to aUnicodeScalarand appending it to aString[…][…]
The various views are all indexable collections, but they are very much not arrays. The index types are weird custom
structs. This means you can’t index views by number […] Instead, you have to start with either the collection’sstartIndexorendIndex, then use methods likesuccessor()oradvancedBy()to move around […] Why not make it easier, and allow indexing with an integer? It’s essentially Swift’s way of reinforcing the fact that this is an expensive operation.