隐式展开可选的布尔值

时间:2014-06-09 20:08:22

标签: swift

Bool类型的隐式展开似乎不起作用:

var aBoolean: Bool!    // nil
aBoolean = false       // false
aBoolean               // false

aBoolean == true       // false
aBoolean == false      // true

if aBoolean {
    "Hum..."            // "Hum..."
} else {
    "Normal"
}

if aBoolean! {
    "Hum..."
} else {
    "Normal"          // "Normal"
}

如果我宣称aBoolean类似于var aBoolean: Bool?,这可能是预期的行为,但在这里,我无法得到它。

这是正确的行为吗?我没有找到任何关于它的文档。

谢谢!

5 个答案:

答案 0 :(得分:8)

第一个测试是检查aBoolean是否存储一个值而不是nil,它确实存在:

if aBoolean {
    "Hum..."            // "Hum..."
else {
    "Normal"
}

第二个测试是检查存储在aBoolean中的实际布尔值,该值为false:

if aBoolean! {
    "Hum..."
} else {
    "Normal"          // "Normal"
}

这是在"隐式包装的选项"中的Swift书中的插图。部分。我认为隐含的解包并不适用于if语句。我同意这很奇怪,但这是Apple的例子:

您仍然可以将隐式解包的可选项视为普通的可选项,以检查它是否包含值:

let assumedString: String! = "An implicitly unwrapped optional string."

if assumedString {
    println(assumedString)
}
// prints "An implicitly unwrapped optional string."

摘自:Apple Inc.“The Swift Programming Language。”iBooks。 https://itun.es/us/jEUH0.l

答案 1 :(得分:6)

不是答案,但如果这确实是隐含式解包布尔值的预期行为,那就相当令人不安了。只要在任何逻辑命题中使用表达式,它就会被解包:

var aBoolean: Bool! = false

if !aBoolean {
    "I'm unwrapping"            // "I'm unwrapping"
}

if aBoolean == false {
    "I'm unwrapping"            // "I'm unwrapping"
}

假设您的代码中有这个,在某些时候您的模型发生了变化,条件反转,您删除了NOT。

if aBoolean {
    "I'm unwrapping"            // <- ouch
}

你刚搞砸了。让我想避免隐式展开。

答案 2 :(得分:2)

你正在进行两次不同的真相检查。

假设:

var aBoolean: Bool!    // nil
aBoolean = false       // false

if aBoolean {
    "Hum..."            // "Hum..."
else {
    "Normal"
}

if aBoolean! {
    "Hum..."
} else {
    "Normal"          // "Normal"
}

...在第一个if aBoolean中,该值未被解包,它只是测试可选类型以确定它是否存储值。

在第二个if aBoolean!中,您正在测试未包装的Bool的真值。

要确定 确实是隐式解包(当没有在条件中使用时),请尝试:

println("value of implicitly-unwrapped aBoolean: \(aBoolean)")

...当aBoolean设置为true时,将打印'true',设置为false时打印'false',而当尚未指定时,打印'nil'。

答案 3 :(得分:1)

以下是清楚显示的行为:

> var bool1 : Bool!
bool1: Bool! = nil
> bool1 = false
> (bool1 ? "yes" : "no")
$R19: (String) = "yes"

在上文中,由于bool1可选(成为Some个实例),因此简单bool1的条件评估为true (它不是nil)。

> var bool2 : Bool = false
bool2: Bool = false
> (bool2 ? "yes" : "no")
$R25: (String) = "no"

bool2不是可选时,简单bool2的条件评估为falsebool2的值)

答案 4 :(得分:0)

使用!将变量声明为“隐式解包”时,它仍然是Optional

这种类型的变量与Objective-C中的标准变量类型非常相似。它可以分配给nil,但是当您访问成员时,您不需要显式解包它。这样就像ObjC一样“不安全”,因为你可以从nil

访问属性

因此,当从Objective-C桥接时,它最常用。但是,它仍然是可选的,唯一的区别是您不需要打开它来访问内容。

我认为这主要是为了支持Swift和Obj-C之间的互操作,并且可能是在纯Swift代码中谨慎使用它的好习惯。 (斯威夫特指南现在很模糊,有人可能很快证明我错了!)