Swift:可选类型(Optional)

来源:互联网 发布:网络打印服务器设置 编辑:程序博客网 时间:2024/05/17 04:46

在我们使用objective-c表示字符串信息的时候,可以用下面方法书写

NSString *str = @"秋恨雪";str = nil;

因为objective-c是弱类型语言,所以这里的str既可以是具体的字符串也可以是nil。但到了Swift中就不可以了,因为Swift是类型安全的语言,一个String类型的变量不可能既能是具体的字符串,又可以为nil(更严格的说String类型的内容只能是字符串)。所以,在Swift中有了可选类型的概念。(其实这一概念也是“借鉴”于其他编程语言,比如C#,只不过在C#中称之为可空类型)

一、可选类型的定义

可选类型的格式: 类型名?

例如:

var phone: String?
问号 "?" 表明phone 的值是可选的,可能是一个String,也可能不存在。

phone的值要么是String类型,要么是nil。

二、可选类型的应用

String有一个toInt方法,可以将字符串转为对应的整数。

有些字符串能转成整数: 比如 "123", 可以转成 123。

有些字符串不能转成整数, 比如 "秋恨雪", 无法转成整数。

因此toInt方法的返回值是一个可选的Int类型(即 Int?)

所以转换结果如下:

let num = "123".toInt()      // 123let num2 = "秋恨雪".toInt()   // nil
注意: num和num2 都是 Int? 类型,而不是 Int类型。

三、可选类型的本质

Int? 其实是对Int的一层包装,它们是两种不同的数据类型。

var num: Int? = 10
可以理解为num包含了 "Some" 和 "None" 这两个 "属性",而上面的操作只是将Int类型的10,包装到了Int? 中的 "Some" 中。示意图如下:


四、强制解包(拆包)

在可选类型的后面加个感叹号 "!" , 就可以将可选类型(包装)的值取出来,赋值给具体类型。

比如下面的写法:

var num: Int? = 10var numValue: Int = num!
其实就是将 "Some" 中的值取出来。示意图如下:


注意:如果可选类型(包装)的值不存在,即 "Some" 的值不存在,任然进行强制解包,会报错。

var num: Int?var numValue: Int = num!

错误信息:fatal error: unexpectedly found nil while unwrapping an Optional value.

因此,在强制解包之前,一定要先检查可选类型(包装)的值是否存在。

针对上面的情况,我们可以使用if语句来检测一个可选类型(包装)的值是否存在。例如:

if let num = "156".toInt() {    println("num的值是\(num)")} else {    println("num的值不存在")}

五、隐式解包(拆包)

默认情况下,如果想将可选类型(包装)的值赋给具体类型,比如将Int?的值赋给Int类型,需要使用感叹号 "!"

如果将可选类型声明为隐式解包。

1. 不用再进行强制解包。

2. 能够自动解包:自动把可选类型(包装)的值取出来赋给具体类型。

隐式解包的声明只需将 "?" 改为 "!" 即可。例如:

var num: Int! = 20var numValue: Int = num // 自动解包
隐式解包的原理:

1. 相当于告诉编译器,这个可选类型的值一直都存在,绝对能取出里面的值。

2. 取值时不用手动加感叹号 "!", 编译器会自动加上一个感叹号 "!" 。

六、"?" 和 "!" 使用场景

1. 在Swift中闭包(如有疑问,请参照我上一章节《Swift:闭包(Closures)》)已经取代了block,定义一个闭包:

var testClosure: ((str1: String) -> Void)?

可以看出,这个闭包的类型后面有一个问号 "?", 因为这个闭包属性很有可能为nil。


2. 在Swift中的IBOutlet的连线操作,就表明了这个控件是一定存在的。例如:

@IBOutlet weak var testLabel: UILabel!

0 0
原创粉丝点击