3 回答
TA贡献1946条经验 获得超4个赞
首先,您必须了解什么是Optional类型。可选类型基本上意味着变量可以是 nil。
例:
var canBeNil : Int? = 4
canBeNil = nil
问号表明一个事实,即canBeNil可以nil。
这将不起作用:
var cantBeNil : Int = 4
cantBeNil = nil // can't do this
要从变量中获取值(如果该值是可选的),则必须将其解包。这仅意味着在结尾处添加一个感叹号。
var canBeNil : Int? = 4
println(canBeNil!)
您的代码应如下所示:
let optionalSquare: Square? = Square(sideLength: 2.5, name: "optional square")
let sideLength = optionalSquare!.sideLength
旁注:
您还可以声明可选内容,以使用感叹号而不是问号来自动展开。
例:
var canBeNil : Int! = 4
print(canBeNil) // no unwrapping needed
因此,修复代码的另一种方法是:
let optionalSquare: Square! = Square(sideLength: 2.5, name: "optional square")
let sideLength = optionalSquare.sideLength
编辑:
您所看到的区别恰好是可选值被包装的症状。在其之上还有另一层。在展开的版本只是表明直对象,因为它是很好,解开。
快速游乐场比较:
在第一种和第二种情况下,对象不会自动解包,因此您会看到两个“图层”({{...}}),而在第三种情况下,您会看到仅一层({...}),因为对象已被自动解包。
第一种情况与第二种情况之间的区别在于,如果optionalSquare将设置为,则后两种情况会给您带来运行时错误nil。在第一种情况下使用语法,您可以执行以下操作:
if let sideLength = optionalSquare?.sideLength {
println("sideLength is not nil")
} else {
println("sidelength is nil")
}
TA贡献1844条经验 获得超8个赞
现有的正确答案很好,但是我发现对于我来说,要完全理解这一点,我需要一个很好的类比,因为这是一个非常抽象和怪异的概念。
因此,让我通过提供正确答案之外的其他观点来帮助那些“头脑敏捷”(视觉思维)开发人员。这是一个很好的类比,对我很有帮助。
生日礼物包装类比
可以将可选商品视为生日礼物,以硬,硬,彩色的包装包裹。
在打开礼物之前,不知道包裹内是否有东西-也许里面什么都没有!如果里面有东西,那可能是另一个礼物,也被包裹了,也可能什么也没有。您甚至可以拆开100个嵌套的礼物,最后发现除了包裹外别无其他。
如果option的值不是nil,那么您已经显示了一个包含某些内容的框。但是,尤其是如果该值未明确键入并且是变量而不是预定义常量,那么您可能仍需要打开该框,然后才能知道该框中内容的具体信息,例如其类型或类型。实际值是。
盒子里装了什么?!比喻
即使在解开变量之后,您仍然像SE7EN的最后一幕中的布拉德·皮特(Brad Pitt)(警告:破坏者和非常R级的粗言秽语和暴力),因为即使在解开当前之后,您仍处于以下情况:您现在有了nil,或一个装有某些物品的盒子(但您不知道是什么)。
您可能知道某物的类型。例如,如果您将变量声明为type,[Int:Any?]那么您将知道您有一个(可能为空)Dictionary,该字典具有整数下标,该整数下标会产生任何旧类型的包装内容。
这就是为什么在Swift中处理集合类型(字典和数组)会有点麻烦。
例子:
typealias presentType = [Int:Any?]
func wrap(i:Int, gift:Any?) -> presentType? {
if(i != 0) {
let box : presentType = [i:wrap(i-1,gift:gift)]
return box
}
else {
let box = [i:gift]
return box
}
}
func getGift() -> String? {
return "foobar"
}
let f00 = wrap(10,gift:getGift())
//Now we have to unwrap f00, unwrap its entry, then force cast it into the type we hope it is, and then repeat this in nested fashion until we get to the final value.
var b4r = (((((((((((f00![10]! as! [Int:Any?])[9]! as! [Int:Any?])[8]! as! [Int:Any?])[7]! as! [Int:Any?])[6]! as! [Int:Any?])[5]! as! [Int:Any?])[4]! as! [Int:Any?])[3]! as! [Int:Any?])[2]! as! [Int:Any?])[1]! as! [Int:Any?])[0])
//Now we have to DOUBLE UNWRAP the final value (because, remember, getGift returns an optional) AND force cast it to the type we hope it is
let asdf : String = b4r!! as! String
print(asdf)
- 3 回答
- 0 关注
- 588 浏览
添加回答
举报