我在else
流的上下文中读取了关键字guard-else
之后用大括号括起来的代码块,必须调用标有noreturn
属性的函数或使用{转移控件{1}},return
,break
或continue
。
最后一部分很清楚,虽然我不太了解第一部分。
首先,即使你没有声明任何返回类型,任何函数都会返回一些东西(至少是一个空元组)。其次,我们何时可以使用throw
函数?文档是否表示某些核心内置方法标有noreturn
?
保护声明的else子句是必需的,必须要么调用 标有noreturn属性或传输程序的函数 使用其中一个来控制守卫声明的封闭范围 以下陈述:
noreturn
这是source。
答案 0 :(得分:11)
首先,即使你没有声明任何返回类型,任何函数都会返回一些东西(至少是一个空元组)。
(@ 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)
可能还有更多。
(备注:其他编程语言中存在类似的注释
或编译器,例如C ++ 11中的[[noreturn]]
,__attribute__((noreturn))
作为GCC扩展,或者_Noreturn
表示
Clang编译器。)
如果它也终止,您可以使用@noreturn
标记自己的功能
进程无条件,,例如通过调用其中一个内置函数,例如
@noreturn func myFatalError() {
// Do something else and then ...
fatalError("Something went wrong!")
}
现在,您可以在guard
语句的else子句中使用您的函数:
guard let n = Int("1234") else { myFatalError() }
@noreturn
函数也可用于标记"不应该的情况
发生"并指出编程错误。一个简单的例子
(摘自Missing return UITableViewCell):
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!")
}
答案 1 :(得分:1)
简单的游乐场,看看它是如何运作的......
//: 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
答案 2 :(得分:0)
例如,考虑一个异步操作,该操作返回值或结果类型错误。我们通常将其写为foolows。
enum Result<Value, Error> {
case success(Value)
case failure(Error)
}
func fetch(_ request: URLRequest,
completion: (Result<(URLResponse, Data), Error>) -> Void) {
// ...
}
现在,如果您知道一个始终返回值的函数,则永远不会出错,那么我们可以编写:
func alwaysSucceeds(_ completion: (Result<String, Never>) -> Void) {
completion(.success("yes!"))
}
当编译器看到从不时,它不会强制您写出所有切换用例,因此您可以按以下方式跳过.failure。
alwaysSucceeds { (result) in
switch result {
case .success(let string):
print(string)
}
}