在Swift中什么是“未包装的值”?

通过遵循本教程,我正在学习iOS 8 / OSX 10.10的Swift ,并且多次使用术语“ 未包装的值 ”,如本段中(在Objects和Class下):


使用可选值时,您可以编写?在方法,属性和下标之类的操作之前。如果前值?是零,之后的所有内容?将被忽略,整个表达式的值为nil。否则,将取消包装可选值,以及?之后的所有内容。作用于未包装的值。在这两种情况下,整个表达式的值都是一个可选值。


let optionalSquare: Square? = Square(sideLength: 2.5, name: "optional square") 

let sideLength = optionalSquare?.sideLength

我不明白,在网上没有运气。


这是什么意思?


编辑

根据Cezary的回答,原始代码的输出与最终解决方案(在操场上测试)的输出之间存在细微差别:


原始码

http://img4.mukewang.com/5d983320000139ed06210256.jpg

塞扎里的解决方案

http://img.mukewang.com/5d9833230001e00e06200423.jpg

在第二种情况下,超类的属性显示在输出中,而在第一种情况下,则显示一个空对象。


两种情况下的结果难道不应该相同吗?


月关宝盒
浏览 557回答 3
3回答

绝地无双

首先,您必须了解什么是Optional类型。可选类型基本上意味着变量可以是 nil。例:var canBeNil : Int? = 4canBeNil = nil问号表明一个事实,即canBeNil可以nil。这将不起作用:var cantBeNil : Int = 4cantBeNil = nil // can't do this要从变量中获取值(如果该值是可选的),则必须将其解包。这仅意味着在结尾处添加一个感叹号。var canBeNil : Int? = 4println(canBeNil!)您的代码应如下所示:let optionalSquare: Square? = Square(sideLength: 2.5, name: "optional square") let sideLength = optionalSquare!.sideLength旁注:您还可以声明可选内容,以使用感叹号而不是问号来自动展开。例:var canBeNil : Int! = 4print(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")}

婷婷同学_

现有的正确答案很好,但是我发现对于我来说,要完全理解这一点,我需要一个很好的类比,因为这是一个非常抽象和怪异的概念。因此,让我通过提供正确答案之外的其他观点来帮助那些“头脑敏捷”(视觉思维)开发人员。这是一个很好的类比,对我很有帮助。生日礼物包装类比可以将可选商品视为生日礼物,以硬,硬,彩色的包装包裹。在打开礼物之前,不知道包裹内是否有东西-也许里面什么都没有!如果里面有东西,那可能是另一个礼物,也被包裹了,也可能什么也没有。您甚至可以拆开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 islet asdf : String = b4r!! as! Stringprint(asdf)
打开App,查看更多内容
随时随地看视频慕课网APP