我在swift中遇到了这种愚蠢的行为,其中强制解包一个可选项不会传播。
来自文档:
尝试使用!访问不存在的可选值会触发运行时错误。在使用之前,请务必确保可选项包含非零值!强行解开它的价值。
重现:
func foo(bar:String?) throws{
print(bar!);
}
和
try foo(nil);
这对我来说似乎不合逻辑或一致,我找不到有关此主题的任何文档。
这是设计吗?
答案 0 :(得分:12)
错误处理
错误处理是响应和恢复的过程 程序中的错误条件。 Swift提供一流的支持 用于投掷,捕捉,传播和操纵可恢复的 运行时的错误。
...
代表和抛出错误
在Swift中,错误由符合的类型的值表示
ErrorType
协议。这个空协议表明类型可以 用于错误处理。
(注意:ErrorType
已在Swift 3中重命名为Error
因此,使用try/catch
处理 Swift错误(符合ErrorType
协议的类型的值)throw
n。
这与运行时错误和运行时异常完全无关
(也与基金会图书馆的NSException
无关。)
请注意,有关错误处理的Swift文档甚至不使用 word" exception",唯一例外(!)in(强调我的):
请注意
Swift中的错误处理在其他方面类似于异常处理 语言,使用try,catch和throw关键字。不像 许多语言的异常处理 - 包括Objective-C-error Swift中的处理不涉及展开调用堆栈,这是一个过程 这可能是计算上昂贵的。就这样,表现 抛出语句的特征与a的特征相当 退货声明。
nil
选项的展开不会throw
a
Swift错误(可以传播)并且无法处理
try
。
你必须使用像这样众所周知的技术
可选绑定,可选链接,检查nil
等。
答案 1 :(得分:5)
这个'自我解释'示例可以帮助您查看引发运行时异常和抛出符合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
引发运行时异常是代码中的致命错误。