迅速的解包exception没有传播
我已经遇到了这种愚蠢的行为,在强制解包可选不传播。
从文档:
试着用! 访问不存在的可选值会触发运行时错误。 在使用之前,一定要确保一个可选项包含非零值! 强迫 – 打开它的价值。
重现:
func foo(bar:String?) throws{ print(bar!); }
和
try foo(nil);
这似乎不符合逻辑或我一致,我无法find任何有关这个问题的文件。
这是由devise?
从文档 :
error handling
error handling是对程序中的错误条件进行响应和恢复的过程。 Swift在运行时为抛出,捕获,传播和处理可恢复的错误提供了一stream的支持。
…
代表和抛出的错误
在Swift中,错误由符合
ErrorType
协议的types值表示。 这个空的协议表明一个types可以用于error handling。
(注意: ErrorType
在Swift 3中已经被重命名为Error
)
所以用try/catch
处理Swift错误 (符合ErrorType
协议的types的值)是throw
n。 这与运行时错误和运行时exception完全无关(也与基础库中的NSException
无关)。
请注意,error handling的Swift文档甚至没有使用“exception”这个词,唯一的例外(!)在(强调我的)中:
注意
Swift中的error handling类似于其他语言的exception处理 ,使用try,catch和throw关键字。 与许多语言中的exception处理不同,包括Swift中的Objective-Cerror handling不涉及展开调用堆栈,这个过程可能在计算上花费很大。 因此,throw语句的性能特征与return语句的性能特征相当。
nil
可选项的展开不会throw
一个Swift错误(可能被传播),不能用try
来处理。
你必须使用众所周知的技术,如可选的绑定,可选的链接,检查nil
等
这个“自我解释”的例子可以帮助你看到引发运行时exception和抛出一个符合ErrorType协议的错误E之间的区别。
struct E: ErrorType{} func foo(bar:String?) throws { if let error = bar where error == "error" { throw E() } print(bar, "is valid parameter, but don't try to access bar.characters, it crash your code! (if bar == nil)") // here is everything OK let bar = bar! // but here it crash!! _ = bar.characters } do { try foo("error") // next line is not accessible here ... try foo(nil) } catch { print("\"error\" as parameter of foo() throws an ERROR!") } do { try foo(nil) // fatal error: unexpectedly found nil while unwrapping an Optional value } catch { }
它打印
"error" as parameter of foo() throws an ERROR! nil is valid parameter, but don't try to access bar.characters, it crash your code! (if bar == nil) fatal error: unexpectedly found nil while unwrapping an Optional value
引发运行时exception是您的代码中的致命错误。