小编典典

什么时候以及如何在Swift中使用@noreturn属性?

swift

我读包含在大括号关键字后的代码块else中一个的上下文中guard- else流动,必须调用标有一个函数noreturn使用属性或传输控制returnbreakcontinuethrow

最后一部分很清楚,而第一部分我不太清楚。

首先,即使您未声明任何返回类型,任何函数都将返回某些内容(至少一个空元组)。其次,什么时候可以使用noreturn函数?文档是否建议一些标记为的内置内置方法noreturn

Guard语句的else子句是必需的,并且必须调用带有noreturn属性标记的函数,或者使用以下语句之一在Guard语句的封闭范围之外传输程序控件:

return

break

continue

throw

这是来源


阅读 284

收藏
2020-07-07

共1个答案

小编典典

首先,即使您未声明任何返回类型,任何函数都将返回某些内容(至少一个空元组)。

(@noreturn已过时;请参阅下面的Swift 3更新。)否,有一些函数可以立即终止进程,并且
返回调用方。这些在Swift中用标记@noreturn,例如

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

可能还有更多。

注: 类似的注释存在于其他编程语言或编译器中,例如[[noreturn]]C ++
11中__attribute__((noreturn))作为GCC扩展或_NoreturnClang编译器。)

@noreturn如果它也 无条件地 终止了进程,则可以标记自己的函数 例如通过调用内置函数之一,例如

@noreturn func myFatalError() {
    // Do something else and then ...
    fatalError("Something went wrong!")
}

现在,您可以在guard语句的else子句中使用函数:

guard let n = Int("1234") else { myFatalError() }

@noreturn函数还可以用于标记“不应发生”的情况并指示编程错误的摘录中提取):

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell: MyTableViewCell

    switch (indexPath.row) {
    case 0:
        cell = tableView.dequeueReusableCellWithIdentifier("cell0", forIndexPath: indexPath) as! MyTableViewCell
        cell.backgroundColor = UIColor.greenColor()
    case 1:
        cell = tableView.dequeueReusableCellWithIdentifier("cell1", forIndexPath: indexPath) as! MyTableViewCell
        cell.backgroundColor = UIColor.redColor()
    default:
        myFatalError()
    }
    // Setup other cell properties ...
    return cell
}

如果不将其myFatalError()标记为@noreturn,则编译器会抱怨默认情况下缺少返回值。


更新: 在Swift 3(Xcode 8 beta 6)中,该@noreturn属性已被Never返回类型替换,因此上面的示例现在写为

func myFatalError() -> Never  {
    // Do something else and then ...
    fatalError("Something went wrong!")
}
2020-07-07