天天看点

Swift实用小册17:类型检查和类型转换

在本章中,你将学会类型检查和类型转换的使用方法。

前言

和​

​Apple​

​​官网或者网上分享的教程类文章不同,我将以实际开发角度讲述​

​Swift​

​​语言的一些概念和用法,方便大家更好地学习和掌握​

​Swift​

​语言。

这同时也是对自己学习​

​Swift​

​语言过程的知识整理。

如有错误,以你为准。

本章概述

在​

​Swift​

​​开发过程中,常常会遇到传输的类型和使用的类型不同的问题,不过好在​

​Swift​

​​是强类型语言,我们可以通过​

​is、as?​

​​和​

​as!​

​三种 操作符来对类型进行判断和强制转换。

我们新建一个​

​PlayGround​

​​项目,命名为​

​SwiftTypeConversion​

​。

Swift实用小册17:类型检查和类型转换

准备工作

在之前的章节中,我们学过父类与子类的关系及创建,这次我们沿用那一章的案例进行说明。示例:

class AppInformation {
    var appName: String
    init(appName: String) {
        self.appName = appName
    }
}

class AppVersion: AppInformation {
    var appVersion: String
    init(appName: String, appVersion: String) {
        self.appVersion = appVersion
        super.init(appName: appName)
    }
}

class AppAuthor: AppInformation {
    var appAuthor: String
    init(appName: String, appAuthor: String) {
        self.appAuthor = appAuthor
        super.init(appName: appName)
    }
}      

上述代码中,我们创建了一个父类​

​AppInformation​

​​,并初始化了一个​

​String​

​​类型的变量​

​appName​

​。

然后创建了两个子类:​

​AppVersion、AppAuthor​

​​,​

​AppVersion​

​​子类中声明了一个​

​String​

​​类型的变量​

​appVersion​

​​,​

​AppAuthor​

​​子类中声明了一个​

​String​

​​类型的变量​

​appAuthor​

​,我们给两个类相应地初始化。

let App = [
    AppVersion(appName: "我的第一个App", appVersion: "1.0.0"),
    AppAuthor(appName: "我的第一个App", appAuthor: "文如秋雨")
]      

上述代码中,我们声明了一个​

​App​

​​常量数组,包含​

​AppVersion​

​​子类和​

​AppAuthor​

​​子类的实例。接下来,我们就可以判断下我们​

​App​

​​数组的实例是在​

​AppVersion​

​​子类里还是在​

​AppAuthor​

​子类里。

Swift实用小册17:类型检查和类型转换

类型判断

当我们接收到一个参数或者对象,需要判断某一个对象是否是某一个特定的类时,我们可以使用​

​is​

​操作符判断接收到的数值是否属于这个类型。示例:

for AppTtem in App {
    if AppTtem is AppVersion {
        print("在AppVersion版本信息里")
    } else if AppTtem is AppAuthor {
        print("在AppAuthor作者信息里")
    }
}      

上述代码中,我们通过​

​for​

​​循环遍历​

​App​

​​数组中的数据,如果​

​App​

​​数组中的实例​

​AppTtem​

​​在​

​AppVersion​

​​子类中,我们打印输出文本信息,如果在​

​AppAuthor​

​子类中,我们也打印输出。

通过​

​is​

​操作符,我们就可以检测实例类型是否属于我们特定的实例类型。

Swift实用小册17:类型检查和类型转换

类型转换

在实例类型转换,我们会使用到了​

​as?、 as!​

​​两种操作符,和​

​try?、try!​

​​操作符概念相似,​

​as?​

​​会用在当我们不太确定是否能转换成功时的场景,而​

​as!​

​则代表了我们几乎一定会转换成功时的强制场景。 

as!建议少用,有可能会由于强制转换失败而导致系统奔溃。

承接上面的例子,我们提前是不知道​

​App​

​​数组中是有哪些实例的,那么这里我们就可以使用​

​as?​

​操作符,来检查并向下转型。示例:

for AppTtem2 in App {
    if let app1 = AppTtem2 as? AppVersion {
        print("\(app1.appName)的版本是\(app1.appVersion)")
    } else if let app2 = AppTtem2 as? AppAuthor {
        print("\(app2.appName)的作者是\(app2.appAuthor)")
    }
}      

上述代码中,我们使用​

​as?​

​​操作符将​

​AppTtem2​

​​类型向下转换类型为​

​AppVersion​

​​类型,如果转换成功,则我们声明的常量​

​app1​

​​就可以存储​

​AppVersion​

​返回来的值。

值得注意的是:

​as?​

​操作符转换没有改变实例,只是简单地把它作为被转换成的类型来使用。
Swift实用小册17:类型检查和类型转换

其他类型转换

另外,我们再来学习下两种类型的转换:​

​Any​

​​和​

​AnyObject​

​的类型转换。

之前我们学习数组的时候,数组会根据内部的值自动判断类型,这里使用的​

​Any​

​类型,是代表这个数据可以是任何类型。示例:

var exampleArray = [Any]()
var exampleArray2 = [AnyObject]()      

上述代码中,我们声明了一个变量数组​

​exampleArray、exampleArray2​

​,它们都是个可以存储任何类型值的空数组,我们可以给这个数据新增任何类型的值。

两者的区别是​

​Any​

​​可以表示任何类型,包括方法类型,​

​AnyObject​

​​可以代表任何​

​class​

​类型的实例。

不过这两个基本没用过,我们创建数组的时候还是先定义好其类型,避免业务上处理报错。

本章代码

import UIKit

class AppInformation {
    var appName: String
    init(appName: String) {
        self.appName = appName
    }
}

class AppVersion: AppInformation {
    var appVersion: String
    init(appName: String, appVersion: String) {
        self.appVersion = appVersion
        super.init(appName: appName)
    }
}

class AppAuthor: AppInformation {
    var appAuthor: String
    init(appName: String, appAuthor: String) {
        self.appAuthor = appAuthor
        super.init(appName: appName)
    }
}

let App = [
    AppVersion(appName: "我的第一个App", appVersion: "1.0.0"),
    AppAuthor(appName: "我的第一个App", appAuthor: "文如秋雨")
]

for AppTtem in App {
    if AppTtem is AppVersion {
        print("在AppVersion版本信息里")
    } else if AppTtem is AppAuthor {
        print("在AppAuthor作者信息里")
    }
}

for AppTtem2 in App {
    if let app1 = AppTtem2 as? AppVersion {
        print("\(app1.appName)的版本是\(app1.appVersion)")
    } else if let app2 = AppTtem2 as? AppAuthor {
        print("\(app2.appName)的作者是\(app2.appAuthor)")
    }
}

var exampleArray = [Any]()
var exampleArray2 = [AnyObject]()