当我分配变量ammo(和ammo2)时,在可选绑定内部我很确定我应该使用!
来取消选中可选项,但是在我第一次尝试时我错误地放了?
并且有点困惑,为什么它仍然有效,是否有人可以在那里投射一些光线?
let soldierA = Soldier(name: "Brian")
soldierA.weapon = Weapon()
soldierA.weapon!.grenadeLauncher = GrenadeLauncher()
let soldierB = Soldier(name: "Gavin")
soldierB.weapon = Weapon()
let soldierC = Soldier(name: "Berty")
soldierC.weapon = Weapon()
soldierC.weapon!.grenadeLauncher = GrenadeLauncher()
soldierC.weapon!.grenadeLauncher!.ammo = 234
let missionTeam = [soldierA, soldierB, soldierC]
for eachSoldier in missionTeam {
if let launcherAvailable = eachSoldier.weapon?.grenadeLauncher? {
var ammo = eachSoldier.weapon!.grenadeLauncher!.ammo // PRETTY SURE THIS IS RIGHT
var ammo2 = eachSoldier.weapon?.grenadeLauncher?.ammo // SHOULD THIS WORK, IT DOES?
println("SOLDIER: \(eachSoldier.name), Weapon has launcher AMMO: \(ammo)")
} else {
println("SOLDIER: \(eachSoldier.name), Weapon does not have launcher ")
}
}
// CLASSES
class Soldier {
var name: String
var weapon: Weapon?
init(name: String) {
self.name = name
}
}
class Weapon {
var ammo = 500
var grenadeLauncher: GrenadeLauncher?
}
class GrenadeLauncher {
var ammo = 20
}
谢谢,我对这是如何工作感到困惑,但我现在看到发生了什么。这是修改后的eachSoldier部分,使用可选绑定和可选链接...
for eachSoldier in missionTeam {
if let weapon = eachSoldier.weapon? {
if let launcher = eachSoldier.weapon?.grenadeLauncher? {
println("SOLDIER: \(eachSoldier.name) Weapon has launcher with \(launcher.ammo) ammo")
} else {
println("SOLDIER: \(eachSoldier.name) Weapon does not have launcher ")
}
} else {
println("SOLDIER: \(eachSoldier.name) does not have weapon ")
}
}
答案 0 :(得分:3)
soldierC.weapon = Weapon()
soldierC.weapon!.grenadeLauncher = GrenadeLauncher()
soldierC.weapon!.grenadeLauncher!.ammo = 234
在当前模式中是正确的。
var ammo = eachSoldier.weapon!.grenadeLauncher!.ammo
隐式展开weapon
及其grenadeLauncher
; 它不关心它们是否在之前被引入,因此如果您的代码在其中任何一个仍然是nil
值时尝试解包,它可能会导致直接崩溃。
var ammo2 = eachSoldier.weapon?.grenadeLauncher?.ammo
尝试访问weapon
及其grenadeLauncher
; 如果该对象不存在,它们将被单独放置,因此没有任何反应,但ammo2
仅为nil
,应用程序可以继续。
因此你的流程可能类似于:
for eachSoldier in missionTeam {
var ammo2 = eachSoldier.weapon?.grenadeLauncher?.ammo
if ammo2 != nil {
println("SOLDIER: \(eachSoldier.name), Weapon has launcher AMMO: \(ammo2)")
} else {
println("SOLDIER: \(eachSoldier.name), Weapon does not have launcher ")
}
}
答案 1 :(得分:0)
除了@holex所说的内容之外,我还想说你的案例为Optional Chaining,如果你在可选项上使用?
代替!
变量(或常量),这意味着如果变量(或常量)不是nil,则检查。换句话说,它有一个价值。
关于可选链接的可爱之处在于您可以将其应用于多个级别。 例如:
让我们说你有这两个类:
class Student{
var subjects: [Subject]?
}
class Subject{
var name: String?
}
你创建了一个变量:
var william = Student()
您可以随时打印第一个主题的名称:
print(william.subjects?[0].name)
注意该print语句的结果是 nil ,而如果你这样解开它:
print(william.subjects![0].name)
您会收到运行时错误