Articles, podcasts and news about Swift development, by John Sundell.

Making types expressible by string interpolation

Published on 27 Sep 2019
Basics article available: Strings

Creating wrapper types for raw values, such as strings and integers, can be a great way to make our code a bit more type-safe and self-documenting — and also gives us dedicated types on which we can implement domain-specific convenience APIs.

For example, here’s such a type that represents a file system path, which can be used to do things like load the contents of a file:

struct Path {
    var string: String
}

func loadFile(at path: Path) throws -> File {
    ...
}

However, while having that dedicated Path type does give us several benefits, it could also make our APIs a bit more cumbersome to use. For example, anytime we want to specify a path using a string literal, we now have to wrap it first:

try loadFile(at: Path(string: "~/documents/article.md"))

To fix that, we can make Path conform to ExpressibleByStringLiteral, which enables us to directly pass a string literal to any API that accepts a Path:

extension Path: ExpressibleByStringLiteral {
    init(stringLiteral value: String) {
        self.string = value
    }
}

try loadFile(at: "~/documents/article.md")

That’s really nice, however, the above won’t work if we’re using any form of interpolation within our string — such as in this case:

// Since this string literal contains interpolation, it won't
// be automatically converted to a Path, and we'll get an error:
try loadFile(at: "/users/\(username)/file.txt")

Thankfully, the above problem is easily fixed. All we have to do is to declare that our Path also conforms to ExpressibleByStringInterpolation — and the compiler will be able to infer the rest:

extension Path: ExpressibleByStringInterpolation {}

We can now express our Path type using any kind of string literal — which makes it much more convenient to use, while still giving us all of the benefits of stronger typing.

Support Swift by Sundell by checking out this sponsor:

Bitrise

Bitrise: Rock-solid, fast continuous integration that’s super easy to configure. In just a few minutes, you can set up builds, tests, and automatic App Store and beta deployments for your project, all running in the cloud on every pull request and commit. Try it for free today.