Swift Substring on a C String

| | 2 Comments| 5:17 PM

String handling in Swift has been a moving target. While following the evolution of performing certain string operations in Swift, I’ve been reminded of the post Joel Spolsky wrote over a decade ago admonishing all of us to get with the program and support Unicode in our applications from day one. While Swift 1.0 didn’t ignore the request, it certainly did make it easier to use “natural” expressions to extract substrings with ranges. Swift 2.0 tossed that out the window, and a top-rated answer on Stackoverflow becomes useless.

Don’t try this at home, it won’t work, but it sure would be nice if it did:

I mean, it works for Python with hello = helloWorld[0:5], why can’t it work in Swift?

Like we said, Swift 2 is taking Joel’s 2003 plea to heart, and working to make us all (painfully) more aware that these aren’t your father’s strings. There is a great summary as to the rationale at mikeash.com so there’s no reason for me to rehash characters vs. graphemes here. And while I “get it”, there’s no doubt its an aggravation trying to remember what magic I need to invoke to get a substring out of what I know is going to be a const char* C-style ASCII-based string. So, I won’t bother trying to remember, I’ll just write it here for you and for me.

A Simple Substring

I’ve been looking at ways to blend more Swift programming in my day-to-day Linux tasks. I really think it has an opportunity to displace some other languages for quick scripts and “devops”-oriented tasks. In this case I wanted a quick way to print out the git revisions of the projects that make up an open source Swift build. Here’s what I came up with:

Getting the first 10 characters of the git revision hash with rev = rev[rev.startIndex...rev.startIndex.advancedBy(9)] is a little more verbose than it should be, but if you are dealing with what you know to be a C-style string, it gets the job done.

Extend It

Fortunately for us, Swift supports extensions, that awesome feature that allows you to tack on some methods to a class you didn’t write and don’t have source access to. Many folks have posted gists of this particular extension which provides a little syntactic sugar for accessing substrings:

With our extension we can indeed write:

Life is good.

2 thoughts on “Swift Substring on a C String”

  1. You say you read Mike Ash’s post, but to have done so would have negated a fair bit of this post. Please don’t add a subscript to String, it’ll regularly do the wrong thing, especially from a performance standpoint. The Swift team didn’t add it just to be difficult.

    In this particular case, just using the “fromCString” factory method does not guarantee anything about the makeup of the resulting String. If you want to guarantee C-style semantics, use String.UTF8View. Furthermore, taking the first 9 of any collection can be done with the instance method “prefix”, which can be used on the CharactersView of the String (which is still probably not what you want), or the UTF8View as well.

    1. Zachary, to the contrary, nothing I’ve done negates Mike Ash’s post. Like I said, I “get it” but I know what is coming across the wire with that fgets, a 40-character ASCII string of a SHA1 hash. No emoji characters, no letters with diacritics. In that case using an extension is no worse than a typealias for readability. We’re talking about a simple script to slice up some strings and print them on standard out.

      Your *hisses angrily* tweet aside, there really is no reason Swift can’t provide a convenience syntax for working with substring extraction, I mean, its not like 40 other languages don’t provide that. https://en.wikipedia.org/wiki/Comparison_of_programming_languages_(string_functions)#substring

Leave a Reply

Your email address will not be published. Required fields are marked *