Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/96.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 什么是“一个”呢;“未包装的价值”;斯威夫特?_Ios_Swift_Ios8 - Fatal编程技术网

Ios 什么是“一个”呢;“未包装的价值”;斯威夫特?

Ios 什么是“一个”呢;“未包装的价值”;斯威夫特?,ios,swift,ios8,Ios,Swift,Ios8,我通过以下方式学习iOS 8/OSX 10.10的Swift,术语“展开值””被多次使用,如本段所述(在对象和类下): 使用可选值时,您可以写入?手术前 例如方法、属性和订阅。如果之前的值为? 是零,一切都结束了吗?是被忽略的,是整体的价值 表达式为零。否则,将展开可选值,,并且 比赛结束后一切都好吗?作用于展开的值。在这两种情况下 整个表达式的值是可选值 我不明白,在网上搜索也不走运 这意味着什么 编辑 从Cezary的回答来看,原始代码的输出和最终解决方案(在操场上测试)之间有一点差异:

我通过以下方式学习iOS 8/OSX 10.10的Swift,术语“展开值””被多次使用,如本段所述(在对象和类下):

使用可选值时,您可以写入?手术前 例如方法、属性和订阅。如果之前的值为? 是零,一切都结束了吗?是被忽略的,是整体的价值 表达式为零。否则,将展开可选值,,并且 比赛结束后一切都好吗?作用于展开的值。在这两种情况下 整个表达式的值是可选值

我不明白,在网上搜索也不走运

这意味着什么


编辑 从Cezary的回答来看,原始代码的输出和最终解决方案(在操场上测试)之间有一点差异:

原始代码

塞扎里溶液

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

在这两种情况下,结果不是应该是相同的吗


相关问答:

首先,您必须了解可选类型是什么。可选类型基本上意味着变量可以是
nil

例如:

var canBeNil : Int? = 4
canBeNil = nil
var canBeNil : Int! = 4
print(canBeNil) // no unwrapping needed
问号表示
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
if let sideLength = optionalSquare?.sideLength {
    println("sideLength is not nil")
} else {
    println("sidelength is nil")
}
旁注:

您还可以使用感叹号而不是问号声明自动展开的选项

例如:

var canBeNil : Int? = 4
canBeNil = nil
var canBeNil : Int! = 4
print(canBeNil) // no unwrapping needed
因此,修复代码的另一种方法是:

let optionalSquare: Square! = Square(sideLength: 2.5, name: "optional square") 
let sideLength = optionalSquare.sideLength
编辑: 您所看到的差异正是可选值被包装的症状。上面还有一层。unwrapped版本只显示直线对象,因为它是未包装的

快速比较:

在第一种和第二种情况下,对象没有自动展开,因此您会看到两个“层”(
{…}
),而在第三种情况下,您只看到一个层(
{…}
),因为对象正在自动展开

第一种情况和第二种情况之间的区别在于,如果
optionalSquare
设置为
nil
,则第二种情况将给您一个运行时错误。使用第一种情况下的语法,可以执行以下操作:

let optionalSquare: Square? = Square(sideLength: 2.5, name: "optional square") 
let sideLength = optionalSquare!.sideLength
if let sideLength = optionalSquare?.sideLength {
    println("sideLength is not nil")
} else {
    println("sidelength is nil")
}

现有的正确答案很好,但我发现要想完全理解这一点,我需要一个很好的类比,因为这是一个非常抽象和怪异的概念

因此,让我帮助那些“右脑”(视觉思维)开发人员,除了给出正确的答案外,还提供了不同的视角。这里有一个很好的类比,对我帮助很大

生日礼物包装类比

想象一下,选购件就像生日礼物一样,用坚硬的彩色包装

在你打开礼物之前,你不知道包装里面有没有东西——也许里面什么都没有!如果里面有什么东西,它可能是另一件礼物,也被包裹着,也可能什么也没有。你甚至可以打开100个嵌套的礼物,最终发现只有包装

如果可选的值不是
nil
,那么现在您已经显示了一个包含某些内容的框。但是,特别是如果值不是显式类型且是变量而不是预定义的常量,那么您可能仍然需要打开该框,然后才能了解框中的具体内容,例如它是什么类型或实际值是什么

盒子里有什么?!类比

即使在你打开变量后,你仍然像布拉德·皮特(警告:破坏者和非常R级的脏话和暴力),因为即使在你打开礼物后,你仍然处于以下情况:你现在有
nil
,或者一个盒子里有东西(但你不知道是什么)。

你们可能知道什么东西的类型。例如,如果您将变量声明为类型,
[Int:Any?]
,那么您就知道有一个(可能是空的)带有整数下标的字典,它生成任何旧类型的包装内容

这就是为什么在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)

“?”表示可选的链接表达式

“!”平均值是力值

Swift高度重视类型安全。整个Swift语言的设计都考虑到了安全性。这是斯威夫特的标志之一,你应该张开双臂欢迎它。它将有助于开发干净、可读的代码,并有助于防止应用程序崩溃

Swift中的所有选项都用
符号进行划分。通过将
设置在声明为可选类型的类型名称之后,实际上您并没有将其转换为
之前的类型,而是转换为可选类型


注:变量或类型
Int
Int?
不同。它们是两种不同的类型,不能相互操作


使用可选的

var myString: String?

myString = "foobar"
这并不意味着您正在使用一种类型的
字符串
。这意味着您正在使用一种类型的
字符串?
(字符串可选,或可选字符串)。事实上,每当你试图

print(myString)
在运行时,调试控制台将打印
可选(“foobar”)
。“
可选()
”部分独立
var myString: String?

print(myString!) 
var something: Any?
// Conditionally
if let thing = something as? Int {
    print(thing) // 0
}

// Optionally
let thing = something as? Int
print(thing) // Optional(0)

// Forcibly
let thing = something as! Int
print(thing) // 0, if no exception is raised
1 + Optional(1) = 2