17-Swift型別轉換
型別轉換可以判斷例項的型別,也可以將例項看做是其父類或子類的例項。
在swift中型別轉換使用is
和as
操作符實現,這兩個操作符提供了一種簡單明瞭的方式去檢查值的型別或轉換其他型別。
一、定義類層次為實際例子
可以將型別轉換用在類和子類的層次結構上,檢查特定型別例項的型別並且轉換這個類例項的型別為這個層次結構中的其他型別:
// 人的類
class Person {
// 名字
var name:String
init(name:String) {
self.name = name
}
}
// 學生的類,繼承自Person
class Student:Person {
// 班級
var grade:String
init(name:String, grade:String) {
self.grade = grade
super.init(name: name)
}
}
// 工人的類,繼承自Person
class Worker:Person {
// 具體職業
var profession:String
init(name:String, profession:String) {
self.profession = profession
super.init(name: name)
}
}
// 常量陣列
let library = [
Student(name: "張三", grade: "一年級(1)班"),
Worker(name: "李明", profession: "教師"),
Student(name: "李四", grade: "二年級(3)班"),
Worker(name: "小紅", profession: "醫生"),
Student(name: "王五", grade: "三年級(6)班"),
]
/** 常量library沒有設定型別,而系統會自動推斷出其型別是Person,
因為Student和Worker類的共同父類是Person
*/
二、檢查型別
用型別檢查操作符is
來檢查一個例項是否屬於特定子型別,若例項屬於那個子型別,型別檢查操作符返回true
,否則返回false
:
// 計算常量陣列library中學生和工作者的個數
var studentCount = 0
var workerCount = 0
for item in library {
// 判斷例項的型別
if item is Student {
studentCount += 1
}
else if item is Worker {
workerCount += 1
}
}
print("學生個數:\(studentCount),工作者的個數:\(workerCount)")
輸出結果:
學生個數:3,工作者的個數:2
三、向下轉型
某型別的一個常量或變數實際上是屬於一個子類,那麼可以嘗試向下轉到子類型別,用型別轉換操作符as?
或as!
。
而向下轉型可能會失敗,型別轉換操作符有兩種形式。條件形式as?
,返回一個試圖向下轉成的型別的可選型別。強制形式as!
把試圖向下轉型和強制拆包結果作為一個混合動作。
當不確定轉型是否成功,建議用條件形式as?
。條件形式的型別轉換總是返回一個可選型別的,且向下轉型不可能的,可選值就是為nil
,這也就可以檢查向下轉型是否成功。
只有當確定向下轉型一定會成功時,才使用強制形式as!
。但試圖向下轉型為一個不正確型別時,這就會導致程式崩潰。
// 因為library系統自動推斷是Person,即item都是Person型別
for item in library {
// 嘗試將item向下轉型,即轉為Student型別,轉換成功即輸出對應結果
if let student = item as? Student {
print("學生:\(student.name) 班級:\(student.grade)")
}
if let worker = item as? Worker {
print("工作者:\(worker.name) 職業:\(worker.profession)")
}
}
輸出結果:
學生:張三 班級:一年級(1)班
工作者:李明 職業:教師
學生:李四 班級:二年級(3)班
工作者:小紅 職業:醫生
學生:王五 班級:三年級(6)班
注意: 型別轉換沒有真正改變例項中的值,即是例項根本就是保持不變的,只是簡單地把例項作為它被轉換成的型別來使用。
四、Any和AnyObject的型別轉換
swift中為不確定型別提供了兩種特殊型別別名:
- AnyObject
可以代表任何類的例項;
- Any
可以表示任何型別,包括方法型別;
- AnyObject型別。例如當我們接收到一個
[AnyObject]
型別陣列,即是"一個任意型別物件的陣列",此時我們可以使用強制形式的型別轉換來處理陣列中的每個元素:
// 定義一個 `[AnyObject]` 型別的陣列
let someObjects:[AnyObject] = [
Student(name: "李明", grade: "九年級(3)班"),
Student(name: "蕭十一", grade: "八年級(7)班"),
Student(name: "王八", grade: "三年級(5)班")
]
// someObjects陣列只包含Student例項,所以可以直接用強制型別(as!)
for object in someObjects {
let student = object as! Student
print("名字:\(student.name) 班級:\(student.grade)")
}
// 更為簡短形式
// 直接將陣列進行型別轉換
for student in someObjects as! [Student] {
print(">>> 名字:\(student.name) 班級:\(student.grade)")
}
輸出結果:
名字:李明 班級:九年級(3)班
名字:蕭十一 班級:八年級(7)班
名字:王八 班級:三年級(5)班
>>> 名字:李明 班級:九年級(3)班
>>> 名字:蕭十一 班級:八年級(7)班
>>> 名字:王八 班級:三年級(5)班
- Any型別。使用Any型別來混合不同型別:
// 可以任意型別的陣列trings
var things = [Any]()
// 整形
things.append(0)
// 浮點型
things.append(3.3)
// 整形
things.append(99)
// 字串
things.append("hello swift")
// Student例項
things.append(Student(name: "多多", grade: "幼兒園(小班)"))
// 閉包
things.append({
(name:String) -> String in
return "hello \(name)"
})
// 將things陣列中元素對應列印出來
for thing in things {
switch thing {
// 轉為整形
case let someInt as Int:
print("整形: \(someInt)")
// 轉為Dounle
case let someDouble as Double:
print("浮點型: \(someDouble)")
// 判斷是否存在字串型別
case is String:
print(">>> 存在有字串")
// 轉為Student型別
case let student as Student:
print("名字:\(student.name) 班級:\(student.grade)")
// 轉為閉包型別
case let speak as String -> String:
print(speak("EndEvent"))
default:
print("好煩躁,不判斷了,不知道什麼型別")
}
}
輸出結果:
整形: 0
浮點型: 3.3
整形: 99
>>> 存在有字串
名字:多多 班級:幼兒園(小班)
hello EndEvent
注:xcode7.3環境
相關文章
- PHP 型別轉換&&型別強制轉換PHP型別
- java型別轉換與強制型別轉換(轉)Java型別
- 型別轉換型別
- java- 型別-轉換:基本型別以及包裝型別的轉換Java型別
- 資料型別,型別轉換資料型別
- js型別轉換JS型別
- 字元型別轉換字元型別
- 3.2 型別轉換型別
- JavaScript 型別轉換JavaScript型別
- Golang型別轉換Golang型別
- 型別轉換(cast)型別AST
- C++中的向上型別轉換和向下型別轉換C++型別
- Java資料型別及型別轉換Java資料型別
- 字元型別轉換成時間型別字元型別
- Oracle Long型別轉換為Clob型別Oracle型別
- interface{} 型別的轉換型別
- JNI常用型別轉換型別
- 資料型別轉換資料型別
- go interface{}型別轉換Go型別
- 型別轉換注意點型別
- 強制型別轉換型別
- 變數型別轉換變數型別
- spark dataframe 型別轉換Spark型別
- 容器,型別轉換。List。型別
- sql server型別轉換SQLServer型別
- 陣列型別轉換陣列型別
- struts 型別轉換器型別
- C++型別轉換C++型別
- 型別轉換工具類型別
- golang的型別轉換Golang型別
- C# 型別轉換C#型別
- 型別轉換運算子型別
- c++ 型別轉換C++型別
- Convert型別轉換型別
- 第11章 使用類——型別轉換(二)將自定義型別轉換為內建型別型別
- 日期型別與String型別的轉換型別
- 將timestamp型別轉換為date型別型別
- go-常用型別轉換Go型別