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

Implementing throwing protocol functions as non-throwing

Published on 05 Nov 2019
Basics article available: Protocols

In Swift, it’s possible to satisfy a throwing function protocol requirement using a non-throwing function, which can be very useful in certain situations. For example, let’s say that we’ve defined a protocol for parsers that enable us tokenize a string in some way:

protocol TokenParser {
    func parseToken(from string: String) throws -> Token
}

While certain implementations of the above protocol will need to throw, that won’t necessarily be true for all conforming types. For example, the below KeywordParser throws, while TextParser doesn’t:

struct KeywordParser: TokenParser {
    func parseToken(from string: String) throws -> Token {
        ...
    }
}

struct TextParser: TokenParser {
    // This will satisfy our protocol requirement, even though
    // this implementation doesn't actually throw:
    func parseToken(from string: String) -> Token {
        ...
    }
}

Since the original declaration of our protocol function is marked as throwing, we’ll always need to call it with try when the exact conforming type isn’t known — regardless of whether the underlying implementation actually throws:

let parsers: [TokenParser] = ...

for parser in parsers {
    // Since all we know about each parser within this iteration
    // is that it conforms to our 'TokenParser' protocol, we'll
    // need to use 'try' when calling its function:
    let token = try parser.parseToken(from: string)
}

However, when dealing with a non-throwing conforming type directly, we can now omit the try keyword — even though the original protocol requirement was marked as throwing:

let parser = TextParser()
let text = parser.parseToken(from: string)

It’s a small feature, but the fact that we can implement a throwing function requirement using a non-throwing one gives us a slightly greater degree of flexibility when conforming to protocols that contain such functions.

Support Swift by Sundell by checking out this sponsor:

Essential Developer

Essential Developer: Learn the most up-to-date techniques and strategies for testing new and legacy Swift code in this free practical course for developers who want to become complete senior iOS developers. This virtual event includes lectures, mentoring sessions, and step-by-step instructions. Click to learn more.