/*
可选类型
要么有值,值等于x;要么没有值,即为 nil。
*/
let possubleNumber = "123"
let convertedNumber = Int(possubleNumber)
/*
convertedNumber 的类型为 Int? 即为 "optional Int"。
暗示该值可能是 Int,或者不是Int,即为 nil。
*/
print(convertedNumber)
/*
输出:
Optional(123)
*/
let possubleNumber2 = "Hello World"
let convertedNumber2 = Int(possubleNumber2)
print(convertedNumber2)
/*
输出:
nil
*/
/*
nil
表示值缺失,不能用于非可选的常量和变量。
在 Objective-C 中,nil 是一个指向不存在对象的指针。
在 Swift 中,nil 不是指针——它是一个确定的值,用来表示值缺失。
var serverResponseCode: Int = 404
serverResponseCode = nil
上面的代码会报错!
var serverResponseCode: Int? = 404
serverResponseCode = nil
这样的代码就不会报错了。
如果代码中有常量或者变量需要处理值缺失的情况,
请把它们声明成对应的可选类型。
*/
/*
声明一个可选常量或者变量但是没有赋值,它们会自动被设置为 nil:
*/
var surveyAnswer: String?
/*
surveyAnswer 的值默认为 nil
*/
/*
可以使用 if 语句和 nil 比较来判断一个可选值是否包含值。
可以使用“相等”(==)或“不等”(!=)来执行比较。
*/
if convertedNumber != nil {
print("convertedNumber 不等于 nil")
}
/*
确定可选类型确实包含值之后,
可以在可选的名字后面加一个感叹号(!)来获取值。
这个惊叹号表示“我知道这个可选有值,请使用它。”
这被称为可选值的强制解析(forced unwrapping)。
*/
if convertedNumber != nil {
print("convertedNumber 的值为 \(convertedNumber!)")
}
/*
使用 ! 来获取一个不存在的可选值会导致运行时错误。
使用 ! 来强制解析值之前,一定要确定可选包含一个非 nil 的值。
*/
/*
可选绑定
用来判断可选类型是否包含值,
如果包含就把值赋给一个临时常量或者变量。
可以用在 if 和 while 语句中,
这条语句不仅可以用来判断可选类型中是否有值,
同时可以将可选类型中的值赋给一个常量或者变量。
*/
if let constantNumber = convertedNumber {
print("constantNumber 的值为 \(constantNumber)")
}
/*
用可选绑定来重写 possibleNumber 这个例子:
*/
if let actualNumber = Int(possubleNumber) {
print("\'\(possubleNumber)\' has an integer value of \(actualNumber)")
} else {
print("\'\(possubleNumber)\' could not be converted to an integer")
}
/*
可以包含多个可选绑定或多个布尔条件在一个 if 语句中,
只要使用逗号分开就行。
只要有任意一个可选绑定的值为nil,
或者任意一个布尔条件为false,
则整个if条件判断为false,
这时你就需要使用嵌套 if 条件语句来处理,
如下所示:
*/
if let firstNumber = Int("4"), let secondNumber = Int("42"), firstNumber < secondNumber && secondNumber < 100 {
print("\(firstNumber) < \(secondNumber) < 100")
}
if let firstNumber = Int("4") {
if let secondNumber = Int("42") {
if firstNumber < secondNumber && secondNumber < 100 {
print("\(firstNumber) < \(secondNumber) < 100")
}
}
}
/*
注意:
在 if 条件语句中使用常量和变量来创建一个可选绑定
,仅在 if 语句的句中(body)中才能获取到值。
相反,在 guard 语句中使用常量和变量来创建一个可选绑定,
仅在 guard 语句外且在语句后才能获取到值,请参考提前退出。
*/
/*
提前退出
条件为真,才会执行guard语句后的代码。
条件为假,会执行else从句中的代码。
guard,总会带有else 语句。
*/
func greet(person: [String: String]) {
guard let name = person["name"] else {
return
}
print("Hello \(name)")
guard let location = person["location"] else {
print("I hope the weather is nice near you.")
return
}
print("I hope the weather is nice in \(location)")
}
greet(person: ["name": "John"])
greet(person: ["name": "Hane", "location": "Cupertion"])
/*
隐式解析可选类型
其实就是一个普通的可选类型,
但是可以被当做非可选类型来使用,
并不需要每次都使用解析来获取可选值。
*/
/*
可选类型String
*/
let possibleString: String? = "An optional string."
/*
需要感叹号来获取值
*/
let forcedString: String = possibleString!
/*
隐式解析可选类型String
*/
let assumedString: String? = "An implicitly unwrapped optional string."
/*
需要感叹号来获取值
*/
let implicitString: String = assumedString
/*
注意:
如果在隐式解析可选类型没有值的时候尝试取值,
会触发运行时错误。
*/
/*
可以把隐式解析可选类型当做普通可选类型来判断它是否包含值
*/
if assumedString != nil {
print(assumedString)
}
/*
也可以在可选绑定中使用隐式解析可选类型来检查并解析它的值
*/
if let definiteString = assumedString {
print(definiteString)
}
/*
注意
如果一个变量之后可能变成nil的话请不要使用隐式解析可选类型。
如果你需要在变量的生命周期中判断是否是nil的话,请使用普通可选类型。
*/