類型轉(zhuǎn)換可以判斷實(shí)例的類型,也可以將實(shí)例看做是其父類或子類的實(shí)例。今天我們就一起來(lái)學(xué)習(xí)swift 。在swift中類型轉(zhuǎn)換使用is和as操作符實(shí)現(xiàn),這兩個(gè)操作符提供了一種簡(jiǎn)單明了的方式去檢查值的類型或轉(zhuǎn)換其他類型。
一、定義類層次為實(shí)際例子
可以將類型轉(zhuǎn)換用在類和子類的層次結(jié)構(gòu)上,檢查特定類型實(shí)例的類型并且轉(zhuǎn)換這個(gè)類實(shí)例的類型為這個(gè)層次結(jié)構(gòu)中的其他類型:
// 人的類class Person {
// 名字
var name:String
init(name:String) {
self.name = name
}
}
// 學(xué)生的類,繼承自Personclass Student:Person {
// 班級(jí)
var grade:String
init(name:String, grade:String) {
self.grade = grade
super.init(name: name)
}
}
// 工人的類,繼承自Personclass Worker:Person {
// 具體職業(yè)
var profession:String
init(name:String, profession:String) {
self.profession = profession
super.init(name: name)
}
}
// 常量數(shù)組let library = [
Student(name: "張三", grade: "一年級(jí)(1)班"),
Worker(name: "李明", profession: "教師"),
Student(name: "李四", grade: "二年級(jí)(3)班"),
Worker(name: "小紅", profession: "醫(yī)生"),
Student(name: "王五", grade: "三年級(jí)(6)班"),
]/** 常量library沒(méi)有設(shè)置類型,而系統(tǒng)會(huì)自動(dòng)推斷出其類型是Person,
因?yàn)?span>Student和Worker類的共同父類是Person
*/
二、檢查類型
用類型檢查操作符is來(lái)檢查一個(gè)實(shí)例是否屬于特定子類型,若實(shí)例屬于那個(gè)子類型,類型檢查操作符返回true,否則返回false:
// 計(jì)算常量數(shù)組library中學(xué)生和工作者的個(gè)數(shù)var studentCount = 0var workerCount = 0
for item in library {
// 判斷實(shí)例的類型
if item is Student {
studentCount += 1
}
else if item is Worker {
workerCount += 1
}
}
print("學(xué)生個(gè)數(shù):\(studentCount),工作者的個(gè)數(shù):\(workerCount)")
輸出結(jié)果:
學(xué)生個(gè)數(shù):3,工作者的個(gè)數(shù):2
三、向下轉(zhuǎn)型
某類型的一個(gè)常量或變量實(shí)際上是屬于一個(gè)子類,那么可以嘗試向下轉(zhuǎn)到子類類型,用類型轉(zhuǎn)換操作符as?或as!。
而向下轉(zhuǎn)型可能會(huì)失敗,類型轉(zhuǎn)換操作符有兩種形式。條件形式as?,返回一個(gè)試圖向下轉(zhuǎn)成的類型的可選類型。強(qiáng)制形式as!把試圖向下轉(zhuǎn)型和強(qiáng)制拆包結(jié)果作為一個(gè)混合動(dòng)作。
當(dāng)不確定轉(zhuǎn)型是否成功,建議用條件形式as?。條件形式的類型轉(zhuǎn)換總是返回一個(gè)可選類型的,且向下轉(zhuǎn)型不可能的,可選值就是為nil,這也就可以檢查向下轉(zhuǎn)型是否成功。
只有當(dāng)確定向下轉(zhuǎn)型一定會(huì)成功時(shí),才使用強(qiáng)制形式as!。但試圖向下轉(zhuǎn)型為一個(gè)不正確類型時(shí),這就會(huì)導(dǎo)致程序崩潰。
// 因?yàn)?/span>library系統(tǒng)自動(dòng)推斷是Person,即item都是Person類型for item in library {
// 嘗試將item向下轉(zhuǎn)型,即轉(zhuǎn)為Student類型,轉(zhuǎn)換成功即輸出對(duì)應(yīng)結(jié)果
if let student = item as? Student {
print("學(xué)生:\(student.name) 班級(jí):\(student.grade)")
}
if let worker = item as? Worker {
print("工作者:\(worker.name) 職業(yè):\(worker.profession)")
}
}
輸出結(jié)果:
學(xué)生:張三 班級(jí):一年級(jí)(1)班
工作者:李明 職業(yè):教師
學(xué)生:李四 班級(jí):二年級(jí)(3)班
工作者:小紅 職業(yè):醫(yī)生
學(xué)生:王五 班級(jí):三年級(jí)(6)班
注意: 類型轉(zhuǎn)換沒(méi)有真正改變實(shí)例中的值,即是實(shí)例根本就是保持不變的,只是簡(jiǎn)單地把實(shí)例作為它被轉(zhuǎn)換成的類型來(lái)使用。
四、Any和AnyObject的類型轉(zhuǎn)換
swift中為不確定類型提供了兩種特殊類型別名:
- AnyObject可以代表任何類的實(shí)例;
- Any可以表示任何類型,包括方法類型;
AnyObject類型。例如當(dāng)我們接收到一個(gè)[AnyObject]類型數(shù)組,即是"一個(gè)任意類型對(duì)象的數(shù)組",此時(shí)我們可以使用強(qiáng)制形式的類型轉(zhuǎn)換來(lái)處理數(shù)組中的每個(gè)元素:
// 定義一個(gè) `[AnyObject]` 類型的數(shù)組let someObjects:[AnyObject] = [
Student(name: "李明", grade: "九年級(jí)(3)班"),
Student(name: "蕭十一", grade: "八年級(jí)(7)班"),
Student(name: "王八", grade: "三年級(jí)(5)班")
]// someObjects數(shù)組只包含Student實(shí)例,所以可以直接用強(qiáng)制類型(as!)for object in someObjects {
let student = object as! Student
print("名字:\(student.name) 班級(jí):\(student.grade)")
}// 更為簡(jiǎn)短形式// 直接將數(shù)組進(jìn)行類型轉(zhuǎn)換for student in someObjects as! [Student] {
print(">>> 名字:\(student.name) 班級(jí):\(student.grade)")
}
輸出結(jié)果:
名字:李明 班級(jí):九年級(jí)(3)班
名字:蕭十一 班級(jí):八年級(jí)(7)班
名字:王八 班級(jí):三年級(jí)(5)班
>>> 名字:李明 班級(jí):九年級(jí)(3)班
>>> 名字:蕭十一 班級(jí):八年級(jí)(7)班
>>> 名字:王八 班級(jí):三年級(jí)(5)班
Any類型。使用Any類型來(lái)混合不同類型:
// 可以任意類型的數(shù)組tringsvar things = [Any]()
// 整形
things.append(0)// 浮點(diǎn)型
things.append(3.3)// 整形
things.append(99)// 字符串
things.append("hello swift")// Student實(shí)例
things.append(Student(name: "多多", grade: "幼兒園(小班)"))// 閉包
things.append({
(name:String) -> String in
return "hello \(name)"
})
// 將things數(shù)組中元素對(duì)應(yīng)打印出來(lái)for thing in things {
switch thing {
// 轉(zhuǎn)為整形
case let someInt as Int:
print("整形: \(someInt)")
// 轉(zhuǎn)為Dounle
case let someDouble as Double:
print("浮點(diǎn)型: \(someDouble)")
// 判斷是否存在字符串類型
case is String:
print(">>> 存在有字符串")
// 轉(zhuǎn)為Student類型
case let student as Student:
print("名字:\(student.name) 班級(jí):\(student.grade)")
// 轉(zhuǎn)為閉包類型
case let speak as String -> String:
print(speak("EndEvent"))
default:
print("好煩躁,不判斷了,不知道什么類型")
}
}
輸出結(jié)果:
整形: 0
浮點(diǎn)型: 3.3
整形: 99
>>> 存在有字符串
名字:多多 班級(jí):幼兒園(小班)
hello EndEvent
注:xcode7.3環(huán)境
原文來(lái)自:簡(jiǎn)書/EndEvent