Swift 良好的编码实践:可选类型 Bool 的 If 语句

Posted

技术标签:

【中文标题】Swift 良好的编码实践:可选类型 Bool 的 If 语句【英文标题】:Swift good coding practice: If statement with optional type Bool 【发布时间】:2014-09-10 15:27:41 【问题描述】:

所以我一直在用 Swift 开发一个应用程序,今天我花了将近一个小时来调试一个完全出乎意料的问题。这一切都源于下面的代码。

if (hero.isAI)  //isAI is a Bool


问题是这个 if 语句总是返回 true。所以我想也许我在某处将 isAI 设置为 true,但最后我意识到我将 isAI 声明为可选类型,如下所示。

var isAI: Bool!

应该是什么时候

var isAI: Bool

这导致 if 语句不检查 isAI 是否为真,而是检查它是否包含值。

所以现在为了安全起见,我一定要像这样写我的 if 语句

if (hero.isAI == true)  //isAI is a Bool


所以我的问题是,我有哪些选择可以在未来避免这个问题?(这个问题似乎非常危险,尤其是在一个大型项目的团队中工作时)。 我是否应该始终明确地编写我的 if 语句,我是否应该完全避免 Bools 的可选类型?

请注意,我在 Xcode Beta 2 中没有这个问题。这个问题是在我升级到 Xcode beta 3 时出现的。我认为是因为在 Beta 2 中,Apple 通过检查其值而不是在 if 语句中处理隐式展开的 Bool检查它是否包含一个值。

最后,下面是一个例子,如果给定一个可选的 Bool 来运行 if 语句,以更好地帮助人们理解问题。

let myBool: Bool! = false

if (myBool) 
    //Runs


if (myBool!) 
    //Won't Run


if (!myBool) 
    //Runs


if (myBool == true) 
    //Won't Run

【问题讨论】:

你为什么有一个可选的布尔值?会很容易避免吗? 我有一个初始化后运行的设置方法。 对不起,我对可选选项有点困惑,为什么声明时是! 而不是? 我选择将 Bool 声明为隐式解包,这样我就不需要每次想使用它时都解包它。也因为我知道我会给它一个价值。通常我根本不需要让它成为可选的,只需在初始化时为其分配一个值,但我有一个单独的设置方法,在初始化之后发生,所以在设置方法运行之前,Bool 在技术上将为零。 包装布尔的问题已在较新的 Swift 版本中得到修复。要检查一个可选项是否为 nil,现在最常将其与 nil 进行比较。所以没有重复的意思了。 【参考方案1】:

这是一个已知问题,正在 SwiftInFlux 存储库上进行跟踪,其中包括来自 Chris Lattner on the Apple developer forums 的引用。

此问题存在于符合以下条件的任何可选内容中 LogicValue 协议(例如,嵌套选项、布尔选项、 等等)。我们认为这是一个严重的问题,需要在 1.0 和 有一些想法,但尚未确定解决方案。

所以,这个问题不仅影响可选的布尔值,还影响任何符合 LogicValue 协议(定义为)的可选类型。

protocol LogicValue 
    func getLogicValue() -> Bool


无论如何,就如何解决这个问题的建议而言,很难推荐任何一种具体的解决方案,因为 Apple 没有说明他们打算在未来如何解决这个问题,但我想继续明确检查 Bool 的值将是要走的路。

if (hero.isAI == true) 
    // stuff    

其实经过一番进一步的阅读,上面列出的引文继续阅读:

对于这种常见情况,最简单的答案是生成一个 警告“if x”并要求某人明确写“if x!= nil" 或 "if x == true" 来明确他们想要什么。

【讨论】:

谢谢你,正是我想要的。很高兴看到他们承认这是一个问题。【参考方案2】:

我的建议是使用这种漂亮的合并 ??

if textfieldDate.text?.isEmpty ?? true 
    // the text is either nil or empty but its all we want to know

【讨论】:

【参考方案3】:

如果 bool 是 Core Data(又名 NSNumber)的一部分,你应该这样做。

if (isHero.isAI?.boolValue != nil)

问候

【讨论】:

以上是关于Swift 良好的编码实践:可选类型 Bool 的 If 语句的主要内容,如果未能解决你的问题,请参考以下文章

使用 Swift 的 Encodable 将可选属性编码为 null 而无需自定义编码

swift1-基础

Swift 中的可选闭包属性

条件绑定的初始化程序必须具有可选类型,而不是“Bool”-firebase

如何在 Swift 中比较两个可选的 NSArray

PFFile 返回 nil 可选值 - Swift 1.2