让 Swift 相信函数由于抛出异常而永远不会返回

2024-01-11

因为 Swift 没有抽象方法,所以我创建了一个方法,其默认实现无条件地引发错误。这会强制任何子类重写抽象方法。我的代码如下所示:

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()
    }
}

问题:因为函数期望返回一个值,而上面的函数没有return语句,编译失败。我需要某种方法来说服编译器该函数永远无法完成执行,因为它总是会引发错误。

当所有错误处理似乎都是库级别的,因此超出了编译器的理解时,如何在 Swift 中完成此操作?是否有任何类型的语言级功能可以(希望优雅地)终止程序的执行?


Swift's @noreturn https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Attributes.html属性将函数和方法标记为不返回其调用者。

作为可能最简单的示例,内置函数的签名abort()'s is:

@noreturn func abort()

这为编译器提供了所需的所有信息。例如,以下内容可以正常编译:

func alwaysFail() -> Int {
    abort()
}

虽然alwaysFail()理论上返回一个Int, Swift 知道执行之后无法继续abort()叫做。

我原来的代码不起作用的原因是NSException.raise是一个 Swift 之前的方法,因此没有@noreturn属性。为了轻松解决这个问题,我可以使用abort():

func shouldBeOverridden() -> ReturnType {
    println("Subclass has not implemented abstract method `shouldBeOverridden`!")
    abort()
}

或者,如果我仍然想使用NSException,我可以使用适当的属性定义扩展

extension NSException {
    @noreturn func noReturnRaise() {
        self.raise()
        abort() // This will never run, but Swift will complain that the function isn't really @noreturn if I don't call a @noreturn function before execution finishes.
    }
}

作为第三种选择,我可以使用从未调用过的abort()NSException.raise()安抚编译器。较早的选项,使用extension,实际上只是执行此操作的抽象:

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()
    abort() // never called
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

让 Swift 相信函数由于抛出异常而永远不会返回 的相关文章

随机推荐