首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Swift中何时以及如何使用@noreturn属性?

在Swift中何时以及如何使用@noreturn属性?
EN

Stack Overflow用户
提问于 2016-06-29 11:46:18
回答 3查看 2.7K关注 0票数 10

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

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

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

卫士语句的one子句是必需的,必须调用带有program属性标记的函数,或者使用以下语句之一调用守护语句的封闭作用域之外的传输程序控件: 返回中断继续抛出

这是来源

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2016-06-29 11:55:17

首先,任何函数都会返回一些内容(至少是一个空的元组),即使您没有声明任何返回类型。

(@ Update已过时;请参阅以下Swift 3更新。)不,有些函数会立即终止进程,而不会返回给调用方。这些在Swift中用@noreturn标记,如

代码语言:javascript
复制
@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]] in C++11、__attribute__((noreturn))作为GCC扩展或_Noreturn用于Clang编译器。)

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

代码语言:javascript
复制
@noreturn func myFatalError() {
    // Do something else and then ...
    fatalError("Something went wrong!")
}

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

代码语言:javascript
复制
guard let n = Int("1234") else { myFatalError() }

@noreturn函数还可用于标记“不应该发生”的情况并指示编程错误。一个简单的例子(来自缺失返回UITableViewCell的摘录):

代码语言:javascript
复制
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返回类型替换,因此上面的示例将编写为

代码语言:javascript
复制
func myFatalError() -> Never  {
    // Do something else and then ...
    fatalError("Something went wrong!")
}
票数 16
EN

Stack Overflow用户

发布于 2016-06-29 12:28:31

简单的操场看看它是怎么工作的..。

代码语言:javascript
复制
//: Playground - noun: a place where people can play

import Foundation
@noreturn func foo() {
    print("foo")
    exit(1)
}

var i: Int?

guard let i = i else {
    foo()
}

print("after foo") // this line will never executed

//prints foo and finish
票数 1
EN

Stack Overflow用户

发布于 2019-04-08 08:24:03

例如,考虑返回结果类型中的值或错误的assync操作。我们通常这样写。

代码语言:javascript
复制
enum Result<Value, Error> {
    case success(Value)
    case failure(Error)
}

func fetch(_ request: URLRequest,
          completion: (Result<(URLResponse, Data), Error>) -> Void) {
    // ...
}

现在,如果您知道一个函数总是返回值,而不是错误,那么我们可以编写:

代码语言:javascript
复制
func alwaysSucceeds(_ completion: (Result<String, Never>) -> Void) {
    completion(.success("yes!"))
}

当编译器看到从不使用时,它不会强迫您编写所有的开关用例,所以您可以跳过.failure,如下所示。

代码语言:javascript
复制
alwaysSucceeds { (result) in
    switch result {
    case .success(let string):
        print(string)
    }
}

参考文献:https://nshipster.com/never/

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38098608

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档