Because Swift does not have abstract methods, I am creating a method whose default implementation unconditionally raises an error. This forces any subclass to override the abstract method. My code looks like this:
class SuperClass {
func shouldBeOverridden() -> ReturnType {
let exception = NSException(
name: "Not implemented!",
reason: "A concrete subclass did not provide its own implementation of shouldBeOverridden()",
userInfo: nil
)
exception.raise()
}
}
The problem: Because the function is expected to return a value, and the above function has no return
statement, compilation fails. I need some way to convince the compiler that this function could never complete execution, because it will always raise an error.
How could this be done in Swift, when all of the error-handling seems be library-level, and therefore beyond the understanding of the compiler? Is there any kind of language-level feature for (hopefully gracefully) terminating the execution of a program?
What about creating a computed property returning a
Never
calledabstract
oroverrideMe
or similar, like so:Example of usage:
It sounds like what you're doing would be better accomplished by creating a protocol and making
shouldBeOverridden
a required method, then having your classes conform to that protocol. https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Protocols.htmlSwift's
@noreturn
attribute marks functions and methods as not returning to their caller.As probably the simplest example, the signature of the built-in function
abort()
's is:This gives the compiler all the information it needs. For example, the following will compile just fine:
Although
alwaysFail()
theoretically returns anInt
, Swift knows that execution can't continue afterabort()
is called.The reason my original code didn't work is because
NSException.raise
is a pre-Swift method, and therefore doesn't have the@noreturn
attribute. To easily solve this, I can either useabort()
:or, if I still want to use
NSException
, I can define an extension with the proper attributeAs a third option, I can just use a never-called
abort()
after anNSException.raise()
to placate the compiler. The earlier option, using anextension
, is really just an abstraction for doing this:In Xcode 8 beta 6 (Swift 3 beta 6) you can now use the
Never
return type instead of@noreturn
to indicate that a function won't return to its caller: