Swift良好的编码实践:如果语句带有可选类型Bool

Epi*_*yte 11 logic ios swift xcode6

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

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

}
Run Code Online (Sandbox Code Playgroud)

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

var isAI: Bool!
Run Code Online (Sandbox Code Playgroud)

什么时候应该

var isAI: Bool
Run Code Online (Sandbox Code Playgroud)

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

所以为了安全起见,我确保写下这样的if-statments

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

}
Run Code Online (Sandbox Code Playgroud)

所以我的问题是,将来有什么方法可以避免这个问题?(这个问题似乎非常危险,特别是在大型项目团队中工作时).我应该总是明确地写出我的if-statment,我应该完全避免Bools的可选类型吗?

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

最后,下面是一个示例,其中if-statements运行给定一个可选的Bool,以更好地帮助人们理解问题.

let myBool: Bool! = false

if (myBool) {
    //Runs
}

if (myBool!) {
    //Won't Run
}

if (!myBool) {
    //Runs
}

if (myBool == true) {
    //Won't Run
}
Run Code Online (Sandbox Code Playgroud)

Mic*_*lum 11

这是一个已知的问题,正在SwiftInFlux回购中被跟踪,其中包括来自Apple开发者论坛的Chris Lattner的这句话.

任何符合LogicValue协议的可选项都存在此问题(例如嵌套选项,可选的bool等).我们认为这个问题需要针对1.0修复并有一些想法,但还没有找到解决方案.

因此,此问题不仅会影响可选的Bools,还会影响符合LogicValue协议(定义为)的任何可选类型.

protocol LogicValue {
    func getLogicValue() -> Bool
}
Run Code Online (Sandbox Code Playgroud)

反正就如何解决这个建议去,就很难推荐任何一个具体的解决方案考虑到苹果并没有给出他们打算如何在将来解决这个指示,但我想,继续明确检查Bool的价值将是最佳选择.

if (hero.isAI == true) {
    // stuff    
}
Run Code Online (Sandbox Code Playgroud)

事实上,在进一步阅读之后,上面列出的引用仍然是:

对于这种常见情况,最简单的答案是产生"if x"的警告并要求某人明确地写"if x!= nil"或"if x == true"以使其明确表达他们想要的内容.

  • 谢谢你,这正是我一直在寻找的。很高兴看到他们承认这是一个问题。 (2认同)