当前位置: 首页 > 面试题库 >

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

薛宜
2023-03-14
问题内容

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

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

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

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

return

break

continue

throw

这是来源。


问题答案:

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

(@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!")
}


 类似资料:
  • 问题内容: 在Swift中,我看到一些类似的方法: 我想知道何时使用@objc?我读了一些文档,但他们说要在Objective-C中调用它时,应添加@objc标志 但是,这是Swift中的私有函数,@ obj的作用是什么? 问题答案: private表示仅在Swift中可见。因此使用@objc在Objective-C中可见。如果您有功能可以快速选择私有功能,则需要此功能。 @objc属性使您的Sw

  • 我正在学习Vue JS,发现有时我们导入{},有时我们导入时没有{}。请问有什么区别? 非常感谢。

  • 问题内容: 什么时候应该使用ThreadLocal变量? 如何使用? 问题答案: 一种可能的(并且是常见的)用法是,当你有一些不是线程安全的对象,但又希望避免同步对该对象的访问时(我正在看着你,SimpleDateFormat)。而是给每个线程自己的对象实例。 例如:

  • 问题内容: 这是成功的send()是“原子的”吗?,因为我认为它实际上实际上涉及系统调用,而不仅仅是在套接字上发送。 哪些系统调用可以被中断,何时中断,中断在哪里处理?我已经了解了SA_RESTART,但并不完全了解发生了什么。 如果我在没有SA_RESTART的情况下进行系统调用,该调用是否可以被与我的应用程序无关但需要操作系统中止我的调用并执行其他操作的任何类型的中断(例如,用户输入)中断?还

  • 问题内容: 我无法理解hibernate何时进入二级缓存以及何时使缓存失效。 这是我目前所了解的: 第二级缓存在会话之间存储实体,作用域为SessionFactory 您必须告诉要缓存的实体,默认情况下不会缓存任何实体 查询缓存将查询结果存储在缓存中。 我不明白的是 hibernate何时会命中此缓存? 假设我已经设置了二级缓存,但没有设置查询缓存。我想缓存我的客户,其中有50000。我可以通过哪

  • 问题内容: 创建ajax请求时,GET over POST有什么优势,反之亦然?我如何知道在任何给定时间应该使用哪个?这是安全意识的决定吗? 此外,实际发送方式有何不同? 问题答案: POST请求是您不想意外发生的请求。GET请求是您可以通过用户通过URL指向浏览器来进行的请求。 GET请求可以非常简单地重复,因为它们的数据基于URL本身。 您应该像考虑常规表单请求(及其GET和POST)一样考虑