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

Referring to overloaded functions

Published on 19 Aug 2019

Here’s a nice little trick that enables an overloaded function/initializer to be passed as an argument. Normally, attempting to do so results in an error, since the compiler can’t know which overload we’re referring to. Thankfully, we can use parameter labels to disambiguate.

// Here File has two initializers that both have the
// same shape: (String) -> File:
struct File {
    init(name: String) {
        ...
    }

    init(path: String) {
        ...
    }
}

func render(_ markdown: Markdown,
            usingTemplateNamed name: String? = nil) {
    // Normally we can pass initializers as functions, but in
    // this case we'll get an error, since the compiler can't
    // know which of the two initializers that we're referring
    // to (since they both accept a String).
    let template = name.map(File.init)
    ...
}

func render(_ markdown: Markdown,
            usingTemplateNamed name: String? = nil) {
    // Solution: We'll include the parameter label for
    // the initializer we're referring to when passing
    // it, to disambiguate between the two candidates.
    let template = name.map(File.init(name:))
    ...
}

Support Swift by Sundell by checking out this sponsor:

Emerge

Emerge: Continuously monitor and reduce your app’s size. Emerge’s easy to use plugins for GitHub and fastlane will automatically scan your app’s binary and provide you with simple, actionable suggestions on how to make it smaller and, in turn, faster for your users to download. Set up a demo now!