返回一个隐式解包的可选

Returning an implicitly unwrapped optional

我正在 Swift 中编写一个程序,它具有各种功能,应该 总是 return 值,但在某些情况下不能,所以程序崩溃并警告用户错误。为了实现这一点,我使用隐式解包的 Optionals 作为我函数的 return 值,这样错误情况就可以 return nil(即使永远不会到达该代码)。它看起来像这样:

func giveMeAThing() -> Thing! {
    if !possibleErrorCase() {
        var thing = createAThingForSure()
        return thing
    }
    else {
        crashAndBurn()
        return nil
    }
}

写这个,感觉有点hacky,所以我的问题是这是否是Swift中隐式解包Optionals的一个很好的使用。有没有更好的方法来构建我的代码来避免这种情况?

我宁愿这样写

func giveMeAThing() -> Thing! {
    if possibleErrorCase() {
        crashAndBurn() // I assume this will not return anyhow
    }
    return createAThingForSure()
}

但这可能只是一个品味问题。

您可能缺少的那块拼图是 @noreturn。如果您将函数声明为 @noreturn,如果您不履行周围的合同,编译器将放弃任何投诉。因此你可以调用这样的方法和 not return any 值,编译器不会抱怨,因为它知道我们要无论如何都要死。例如,fatalErrorabort 就是这样声明的。

因此,以下是合法的:

func f() -> String {
    fatalError("oooooops")
}

即使我们未能履行 returning 值的约定,也能编译,因为 @noreturn(在 fatalError 的声明中)撕毁了约定并刷新了碎片下厕所。

解决同一问题的另一种可能方法是使用 assert。如果不满足条件,这会为您崩溃和燃烧。因此,在您的示例中:

func giveMeAThing() -> Thing {
    assert(!possibleErrorCase(), "gaaaaah!") // crash and burn if error case
    return createAThingForSure()
}

缺点是默认情况下所有断言都会在发布的应用程序中成功。但它在开发过程中很棒,毕竟你的应用程序无论如何都不应该崩溃和燃烧。

您不需要隐式展开的可选值,因为您不希望第二种情况 return 任何值。

如评论者所述,在失败情况下使用 fatalError