为什么Swift的致命错误的论点是@autoclosure?

时间:2016-05-09 10:14:37

标签: swift

我在Swift周围发现fatalError有这个签名:

@noreturn public func fatalError(@autoclosure message: () -> String = default, file: StaticString = #file, line: UInt = #line)

为什么以这种方式定义此函数的任何特定原因?有什么问题:

@noreturn public func fatalError(message:String = default, file: StaticString = #file, line: UInt = #line) {
    //Termination code
}

请注意,我了解@autoclosure的工作原理,而这个问题与其用法无关;但是关于可以使用这种模式的用例。

2 个答案:

答案 0 :(得分:2)

它用于可选地评估语句以减少开销。

对于此代码

fatalError("\(someExpansiveComputation())")

如果使用正常参数传递定义函数,则始终会调用someExpansiveComputation(),即使在生成构建中也是如此。

但是对于@autoclosurefatalError的实现可以选择不调用闭包,以避免调用someExpansiveComputation()的开销

可能的实现可以是

@noreturn public func fatalError(message:String = default, file: StaticString = #file, line: UInt = #line) {
    if debug || errorReportingEnabled {
        log(message()) // only compute the message if necessary 
    }
    abort()
}

答案 1 :(得分:1)

简短回答

减少构建很可能无法显示的错误消息的开销。

当您调用public void setVersion(Long version) { this.version = version; } 函数时,可能会有大量信息用于构建错误消息。这可能需要一些微不足道的处理能力,当涉及致命错误时,希望它不会经常发生,因此最好只在需要时构建错误消息,而不是每次在致命之前构建它遇到错误调用,甚至没有使用。

fatalError使您能够为函数提供有关如何撰写错误消息而无需完成所有工作所需的所有资源和说明。当调用致命错误函数时,它将自行决定是否需要调用提供的闭包来评估它将打印的字符串。