我在Swift中编写一个程序,它具有应该总是返回值的各种函数,但在某些情况下不能,因此程序崩溃并警告用户错误。为了实现这一点,我使用隐式解包的Optionals作为我的函数的返回值,以便错误情况可以返回nil(即使永远不会达到该代码)。它看起来像这样:
func giveMeAThing() -> Thing! {
if !possibleErrorCase() {
var thing = createAThingForSure()
return thing
}
else {
crashAndBurn()
return nil
}
}
写这个,感觉有点hacky,所以我的问题是这是否很好地利用了Swift中隐式解包的Optionals。是否有更好的方法来构建我的代码以避免这种情况?
答案 0 :(得分:2)
我宁愿把它写成
func giveMeAThing() -> Thing! {
if possibleErrorCase() {
crashAndBurn() // I assume this will not return anyhow
}
return createAThingForSure()
}
但这可能只是一个品味问题。
答案 1 :(得分:2)
你可能缺少的那块拼图是@noreturn
。如果您将函数声明为@noreturn
,则编译器会在您不履行周围合同时放弃任何投诉。因此,您可以调用这样的方法并且不返回任何值,编译器不会抱怨,因为它知道我们将会死。例如,fatalError
和abort
以这种方式声明。
因此,以下是合法的:
func f() -> String {
fatalError("oooooops")
}
即使我们未能履行返回值的合同,也会编译,因为@noreturn
(在fatalError
的声明中)撕毁合同并将碎片冲到马桶上。
解决同一问题的另一种可能方法是使用assert
。如果不满足条件,这会导致您崩溃并烧伤。所以,在你的例子中:
func giveMeAThing() -> Thing {
assert(!possibleErrorCase(), "gaaaaah!") // crash and burn if error case
return createAThingForSure()
}
缺点是默认情况下所有断言都在发货应用中成功。但它在开发过程中非常棒,毕竟你的运送应用程序不应该崩溃和烧毁。
答案 2 :(得分:0)
您不需要隐式展开的可选项,因为您不希望第二种情况返回任何值。
正如评论者指出的那样,在失败案例中使用fatalError
。