1.可选项(Optional-?)
Swift语言要求所声明的变量属性和常量属性必须有个默认值,常量定义的时候一定带有值,所以对变量提出了Optional概念,在类型名称后面加个问号?来定义一个可选项。
主要格式为:
var 变量名:变量类型?或var 变量名:变量类型?= 变量值;
1.1强制解包(Forced Unwrapping)
从可选项中取出数据,使用感叹号! 举个🌰:
//定义name为可选项
var name : String? = "Chloe"
//强制解包
var rename : String = name!
1.2隐式解包
有些情况下,可选项在定义是会赋一个初始值,这种情况可以不必每次都进行解包,可以在类型后面加个感叹号!定义一个隐式解包的可选项。
主要格式为:
var 变量名:变量类型!或var 变量名:变量类型! = 变量值举个🌰:
//定义name为可选项
var name : String!= "Chloe"
//强制解包
var rename : String = name
强制解包感叹号放在变量后面,隐式解包感叹号放在变量类型后面
2.可选项是否有值判断方法
主要介绍可以判断可选项是否有值的几个特别方法;其中可选项绑定包括:if-let、while-let、guard-let。
2.1 三目运算: ? :
主要格式:
条件 ? 值1: 值2满足条件时返回值1,不满足条件时返回值2;
var i : Int?
let ternary = i != nil ? i! : -1
print("Value of i is \(ternary)")//打印结果:Value of i is -1
2.2 if-let:可选项绑定(Optional Binding)
可以使用可选项绑定来判断可选项是否包含值;如果有值就把值赋给一个临时的常量(let)或者变量(var),并返回true,否则返回false;
举个🌰:
var desc: String? = "Optionals"
if let temp = desc{
print(temp)
}else{
print("No description")
}
//打印结果:Optionals
附加:
if语句中可以使用逗号分隔多个可选对象:var optionalX :String? = "x" var optionalY :String? = "y" if let x = optionalX, let y = optionalY { print(x) //prints "x" print(y) //prints"y" } else{ print("One or more Optional can't be unwrapped") }等价于:判断
optionalX != nil && optionalY != nil
2.2 while-let:可选项绑定(Optional Binding)
注意:while只要符合条件遍历就会执行,只有遇见不符合条件的情况遍历才会停止,所以while-let慎用,当没有符合条件的数据时,遍历是没办法停止的。 举个🌰:
var strs = ["10","20","abc","-20","30"]
var index = 0
var sum = 0
while let num = Int(strs[index]) ,num > 0{
sum += num
index += 1
}
print(sum)//打印结果:30
2.3 ??-空合并运算符(Nil-Coalescing Operator)
主要格式:
a ?? b
1)其中a是可选项;
2)b是可选项或者不是可选项;
3)b跟a的存储类型必须相同;
4)如果a不为nil,就返回a;
5)如果b不为nil,就返回b;
6)如果b不是可选项,返回a自动解包;
7)空合并运算结果赋值给常量或变量时,类型一般与??右边的类型相同;
8)多个空合并运算符一起使用时,从左至右依次运算,赋值给常量或变量时常量或变量的类型与最右边的相同。
举个🌰1:
var a : Int? = 10
var b : Int? = 30
var c = a ?? b
print(c)//打印结果:Optional(10)
print(c!)//打印结果:10;对c进行了强制解包
此时:c类型为Int?;不论是从代码中,还是从注释中都可以看出来。
举个🌰2:
var a : Int? = 10
var b : Int = 30
var c = a ?? b
print(c)//打印结果:10
此时:c类型为Int;
附加:
??和if-let一起使用例子:var optionalX :String? = "x" var optionalY :String? = "y" if let z = optionalX ?? optionalY { print(z) //打印结果: "x" }等价于:
optionalX != nil || optionalY != nil
2.4 guard-let
guard语句条件为false时才执行大括号中的代码,大括号中的代码必须要写退出语句,一般形式如下:
guard 条件 else{
//do something
退出当前作用域
//return、break、continue、throw error
}
附加:
1)if-let、while-let语句进行可选项绑定时,绑定的常量、变量不能在外层作用域中使用,可以在内层作用域中使用;
2)guard-let语句进行可选项绑定时,绑定的常量、变量能在外层作用域中使用;但不能在内存作用域中使用
举个🌰:
func testFunc(){
var a : String? = "a"
if let c = a {
print(c)打印结果:a
}
print(c)//报错:Cannot find 'c' in scope
}
func testFunc(){
var a : String? = "a"
guard let c = a else{
print(c)//报错:Cannot find 'c' in scope
return
}
print(c)//打印结果:a
}
2.5 属性名+? : 实现可选项绑定
举个🌰:
var num1 : Int? = 5
num1? = 10
print(num1)//打印结果:10
var num1 : Int? = nil
num1? = 5
print(num1)//打印结果:nil
其中num1?会先判断num1是否为nil,不为nil则赋值为10;为nil则不进行赋值。也是一种形式的可选项绑定。
3.Optional本质
Optional本质是枚举,下面是源代码:
@frozen public enum Optional<Wrapped> : ExpressibleByNilLiteral {
case none
case some(Wrapped)
}
所以可选项可以使用Switch-case,举个🌰:
var age : Int? = 10
switch age{
case let .some(v)://等价于case .some(let v)
print("1",v)
case .none://age为nil时
print("2")
}