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.