Swift可选型

Swift可选型

Optional在swift是一个非常重要的特性,可以说是swift的点睛之笔!在swift当中,如果你不显式的制定一个变量的类型为optional,程序是无法知悉这个变量为可选型的!

swift当中的可选型(optional)在目前看来,没有其它语言有相同的概念可以拿来类比!但是,在其它语言当中的nil或者null,可以帮助我们来理解swift的optional!但是,这两者完全没有可比性!

在swift当中,可选型表示一个无法确定的事物,这里的不能确定是不能确定其有没有,而不是是确定其取值的量!因此,定义可选型变量的情况下,变量的类型可以是nil。不恰当的理解方式可以是,在swift当中,optional更像是一种类型!这个类型可以是nil,或者空!

需要注意的是,值类型的变量当中,系统默认的值并非optional!比如Int,Double,Bool等等!

0x00 声明可选型

1
2
3
4
var name1 = "Jill"
var name2:String? = "Jack"
print(name1)
print(name2)

我们可以通过添加?的形式来定义一个可选型!在上面的例子当中,String?就表示name2是一个字符串类型的optional!这里我们初始化name2为Jack,如果我们不初始化的话,name2的值则为nil!

而,name1,则不是一个可选型!需要注意的是上述例子当中的name1,是一个String类型的变量,但是name2则是一个包含值的String可选型!

1
2
3
在playground当中,name1、name2的print值分别为(请尝试)
jill
Optional("Jack")

对于name2这种类型的数据,我们需要拆包!解包(拆包)的方式有很多种,一般情况下,我们可以通过if let来解包

1
2
3
4
5
# EG:::
var name: String?
if let name = name {
print(name)
}

0x01 强制解包Forced unwrapping

在访问一个可选值的时候,我们经常会得到一个optional!这个时候,我们可以通过!来强制解包!感叹号!强制解包的时候,表示我们十分肯定变量有值!也就是我们需要确定被强制解包的变量是安全的!否则程序会出错!

1
2
var name2: String? = "Jack"
print(name2!)

对于没有使用!的时候,name2的值为Optional("jack"),而在使用了之后,则为"Jack"

如果在没有赋值的情况下强制解包,我们会得到一个运行时错误!

1
2
3
name2 = nil //赋初值
print(name2) //得到nil
print(name2!) //得到错误

0x02 条件解包Conditional unwrapping

除了强制解包之外,我们也可以使用if或者if let来对Optional解包!

0x02-01 if解包

在使用可选型之前,我们需要先确定其值是否为某一个取值或者需要确定其是否有值!

1
2
3
4
5
if name2 == "Jack" {
print("Hello, \(name2)")
} else {
print("Hello, Empty")
}

例子当中的if不但判断了name2是否为空,而且也判断了值指定为Jack!

使用if解包,不单单可以使用在String?上,事实上,它可以作用在任何Optional上!只要if的条件是Bool类型即可!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var i:Int? = 10
var j:Int?
print(i) //Optional(10)
print(j) //nil
i == 10 //true
i == 8 //flase
i > 0 //true
i == nil //false
i != nil //true
j == 10 //false
j > 0 //false
j == nil //true

这里我们声明了两个可选型的Int,其中i赋初值为10,j没有赋初值,但是作为可选项,它有nil默认值。我们可以使用上面提到的任何一种比较操作来执行两个可选型的数据!

在没有赋值的情况下,Int?的默认值是nil;而,Int则需要赋值之后才能使用;

对于Optional的Int?,我们可以赋值nil,但是Int,我们却不能赋值为nil!

0x02-02 if let解包

我们还可以使用if let方式来解包!使用这种方式解包时,我们可以使用临时变量(常量)来接受解包之后的值!

1
2
3
4
5
if let n = name2 {
print("Hello \(n)")
} else {
print("Hello Guest")
}

例子当中的name2有初值,所以这里执行了if分支,而不是else分支!当name2没有初值时,则会执行else分支!

0x03 使用可选型Optional

在使用Optional时,我们已经明白了以下问题:

  1. 我们已经知晓了如何声明一个可选型,并且知道如何使用条件语句将其解包;
  2. 我们可以使用判断语句来使用可选型数据;
  3. 我们可以通过赋值为nil来移除一个可选项的值;
  4. 在赋值的时候,我们只能向optional赋值为nil,如果变量不为optional,我们会得到报错提示!
  5. 只有在optional被拆包时,我们方可安全的使用!如果optional没有拆包,我们会得到错误!

在swift当中,所有的变量都必须在有赋值之后才可以使用!只有可选型的变量不需要赋值(实际上optional的值时隐式申明成为nil的)!

1
2
3
4
5
6
7
8
9
10
11
var name3 = "Jill"
var name4: String? = "Jack"
func hello(name: String) -> String {
return "Hello \(name)"
}
hello(name3) //Hello Jill
hello(name4) //Error
hello(name4!) //hello Jack
name4 = nil
hello(name4) //Error

例子当中的传入参数name为非可选,因此在传入可选值的时候就报错了!同时传入nil也是有错误的!

下面,我们尝试将其改编成为可以传可变类型的方法!

1
2
3
4
5
6
7
8
9
10
func optionalHello(name: String?) -> String {
if let n = name {
return "Hello \(n)"
} else {
return "Hello"
}
}
optionalHello(nil) //Hello
optionalHello(name3) //Hello Jill
optionalHello(name4) //Hello Jack

例子当中,虽然传入的是optional,但是我们在方法体当中存在了解包,所以程序没有错误!

0x04 字典Dictionary

下篇文章将介绍Swift:字典与可选型