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
String
type 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
String
is pretty obscure.UTF16View
has no public initializers and few mutating functions. The solution is to use the globaltranscode
function, which works with theUnicodeCodecType
protocol. There are three implementations of this protocol:UTF8
,UTF16
, andUTF32
. Thetranscode
function can be used to convert between them. It’s pretty gnarly, though. For the input, it takes aGeneratorType
which 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-32
code unit to aUnicodeScalar
and appending it to aString
[…][…]
The various views are all indexable collections, but they are very much not arrays. The index types are weird custom
struct
s. This means you can’t index views by number […] Instead, you have to start with either the collection’sstartIndex
orendIndex
, 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.