所以在Objective-C中使用布尔值时,可以并且鼓励使用变量的非零值来编写代码,因为它是布尔值,这意味着你可以编写如下代码:
if (someBool) {
// Stuff
}
另外,有理由不鼓励使用以下代码:
if (someBool == YES) {
// Might run into problems here
}
更好地解释了针对另一个布尔值检查布尔值的原因here,但简单地说问题就在于,当您直接将等式与YES
或NO
进行比较时,实际上分别与1
和0
进行比较。由于Objective-C允许使用非零值作为真值,因此您最终可能会将与YES
相对应的事物进行比较,并将表达式解析为NO
,例如
int trueNumber = 2;
if (trueNumber == YES) {
// Doesn't run because trueNumber != 1
}
这在Swift中仍然是一个问题吗?抛开代码风格问题,如果我看到类似下面的内容
var someBool = true
if someBool == true {
// stuff
}
是一个问题,还是不重要?这些C风格的比较是否仍然在幕后发生,或者Swift BooleanType中是否存在可以防止这些问题的内容?
答案 0 :(得分:2)
Swift有Bool类型。这与objective-c的BOOL不同,后者不是实际类型。它实际上是typedef unsigned char。当swift期望Bool你必须给它Bool否则它是编译错误。以下代码将无法编译,因为check不是Bool
let check = 2
if check {
}
但是这会有效,因为==返回Bool
let check = 2
if check == 2 {
}
答案 1 :(得分:2)
Swift中的if <something> {}
结构要求<something>
符合BooleanType
协议,该协议的定义如下:
public protocol BooleanType {
/// The value of `self`, expressed as a `Bool`.
public var boolValue: Bool { get }
}
如果类型不符合此协议,则抛出编译时错误。如果在标准库中搜索此协议,则会发现唯一符合此协议的类型是Bool
本身。 Bool
是一种可以是true
或false
的类型。不要将其视为数字1
或0
,而应将其视为开/关右/错。
现在这个协议可以符合你想要的任何名义类型,例如:
extension Int : BooleanType {
public var boolValue : Bool {
return self > 0
}
}
现在如果你这样做(你不应该诚实地),你自己定义了什么是“真”和“假”的意思。现在你可以像这样使用它(再次,不要这样做):
if 0 {
...
}
答案 2 :(得分:0)
要理解ObjC风格,你需要回到C.在C中,这句话:
if (something) {
// Do something
}
如果false
为空或0,将评估为something
。其他所有评估为true
。问题是C没有布尔类型。 Objective-C添加了YES
和NO
,基本上是1和0.所以:
if (aBoolValue == YES) { } // Work as expected
if (anIntValue == YES) { } // False unless anIntValue == 1
“气馁”的建议是与C中的行为保持一致.Swift没有这样的向后兼容性要求。你不能写这些:
if anIntValue { } // Syntax error
if anObject { } // Syntax error
相反,表达式必须求值为布尔值:
if anIntValue != 0 { } // Ok
if anObject != nil { } // Ok