Swift學(xué)習(xí)_類型檢查符is和類型轉(zhuǎn)換符as

Swift

1.類型檢查符is

類型檢查操作符is,可以檢查一個(gè)對(duì)象是不是某個(gè)類的對(duì)象,如果是,則返回true,否則返回false

class Person{
    
    var name:String?
    init(name:String) {
        
        self.name = name;
    }
}

class Employee: Person {
    
    var company:String
    init(name:String,company:String) {
        
        self.company = company
        super.init(name: name)
    }
}

class Student: Person {
    
    var school:String?
    init(name:String,school:String) {
        
        self.school = school
        super.init(name: name)
    }
}

let employee1 = Employee(name:"張三",company:"apple公司")
let employee2 = Employee(name:"李四",company:"google公司")

let student1 = Student(name:"小明",school:"中關(guān)村一小")
let student2 = Student(name:"小花",school:"中關(guān)村二小")
let student3 = Student(name:"小路",school:"中關(guān)村二小")

let members = [employee1,employee2,student1,student2,student3];

var employeeCount = 0
var studentCount = 0

for item in members{
    
    if item is Employee{
        employeeCount += 1;
    }else if item is Student{
        studentCount += 1;
    }
    
}

print("職員的人數(shù):\(employeeCount)人")        // 打印   職員的人數(shù):2人
print("學(xué)生的人數(shù):\(studentCount)人")         // 打印   學(xué)生的人數(shù):3人

2.類型轉(zhuǎn)換as操作符

類型轉(zhuǎn)換時(shí)將一個(gè)類型轉(zhuǎn)換為另外一個(gè)類型,但是前提是有繼承關(guān)系的,對(duì)象的類型之間才可以轉(zhuǎn)換,將子類轉(zhuǎn)換成父類,是向上轉(zhuǎn)換,一般都會(huì)轉(zhuǎn)換成功,將父類轉(zhuǎn)換成子類是向下轉(zhuǎn)換,可能會(huì)失敗

類型轉(zhuǎn)換的操作符有兩種形式:as?和as!,條件形式as?返回目標(biāo)類型的可選值,強(qiáng)制形式as!把向下轉(zhuǎn)型和強(qiáng)制解包轉(zhuǎn)型結(jié)果結(jié)合為一個(gè)操作

as!操作符是類型轉(zhuǎn)換的強(qiáng)制格式,如果可以轉(zhuǎn)換,則會(huì)返回轉(zhuǎn)換了格式的對(duì)象,如果無法轉(zhuǎn)換就會(huì)拋出運(yùn)行時(shí)錯(cuò)誤。因此除非百分之百確定可以轉(zhuǎn)換,否則不應(yīng)該使用as!來進(jìn)行強(qiáng)制類型轉(zhuǎn)換。

和is操作符非常類似,類型轉(zhuǎn)換的規(guī)則是,某個(gè)類的對(duì)象可以轉(zhuǎn)換為自己這個(gè)類(這個(gè)其實(shí)是廢話),子類可以向上轉(zhuǎn)換為超類,但超類不能向下(downcast)轉(zhuǎn)換為子類。除非某個(gè)子類的對(duì)象表現(xiàn)形式為超類,但實(shí)際是子類,這時(shí)可以使用as!進(jìn)行向下轉(zhuǎn)換(downcast)。

class MediaItem{
    
    var name: String
    init(name: String) {
        
        self.name = name
    }
}

class Movie: MediaItem {
    
    var director: String
    init(name: String, director: String) {
        
        self.director = director
        super.init(name: name)
    }
}
class Song: MediaItem {
    
    var artist: String
    init(name: String, artist: String) {
        
        self.artist = artist
        super.init(name: name)
    }
}

let library = [
    Movie(name: "Casablanca", director: "Michael Curtiz"),
    Song(name: "Blue Suede Shoes", artist: "Elvis Presley"),
    Movie(name: "Citizen Kane", director: "Orson Welles"),
    Song(name: "The One And Only", artist: "Chesney Hawkes"),
    Song(name: "Never Gonna Give You Up", artist: "Rick Astley")
]


var movieCount = 0
var songCount = 0

for item in library {
    if let movie = item as? Movie {
        print("Movie: '\(movie.name)', dir. \(movie.director)")
    } else if let song = item as? Song {
        print("Song: '\(song.name)', by \(song.artist)")
    }
}
1.首先試圖將 item 下轉(zhuǎn)為 Movie 。因?yàn)?item 是一個(gè) MediaItem 類型的實(shí)例,它可能是一個(gè) Movie ;同樣,它也可能是一個(gè) Song ,或者僅僅是基類 MediaItem 。因?yàn)椴淮_定, as? 形式在試圖下轉(zhuǎn)時(shí)將返回 一個(gè)可選值。 item as? Movie 的返回值是 Movie? 或者說“可選 Movie ”。
2.當(dāng)向下轉(zhuǎn)型為 Movie 應(yīng)用在兩個(gè) Song 實(shí)例時(shí)將會(huì)失敗。為了處理這種情況,上面的例子使用了可選綁定(op tional binding)來檢查可選 Movie 真的包含一個(gè)值(這個(gè)是為了判斷下轉(zhuǎn)是否成功。)可選綁定是這樣寫 的“ if let movie = item as? Movie ”,可以這樣解讀:

“嘗試將 item 轉(zhuǎn)為 Movie 類型。若成功,設(shè)置一個(gè)新的臨時(shí)常量 movie 來存儲(chǔ)返回的可選 Movie 中的 值”

3.若向下轉(zhuǎn)型成功,然后 movie 的屬性將用于打印一個(gè) Movie 實(shí)例的描述,包括它的導(dǎo)演的名字 directo r 。相似的原理被用來檢測(cè) Song 實(shí)例,當(dāng) Song 被找到時(shí)則打印它的描述(包含 artist 的名字)。

注意
轉(zhuǎn)換沒有真的改變實(shí)例或它的值。根本的實(shí)例保持不變;只是簡(jiǎn)單地把它作為它被轉(zhuǎn)換成的類型來使用。

2.1. as!使用場(chǎng)合

向下轉(zhuǎn)型(Downcasting)時(shí)使用。由于是強(qiáng)制類型轉(zhuǎn)換,如果轉(zhuǎn)換失敗會(huì)報(bào)運(yùn)行錯(cuò)誤。

class Animal {
    
}

class Cat: Animal {
    
}
let animal:Animal = Cat()
let cat = animal as! Cat
print("as! --- \(cat)")

2.2. as?使用場(chǎng)合

as? 和 as! 操作符的轉(zhuǎn)換規(guī)則完全一樣。但 as? 如果轉(zhuǎn)換不成功的時(shí)候便會(huì)返回一個(gè) nil 對(duì)象。成功的話返回可選類型值(optional),需要我們拆包使用。
由于 as? 在轉(zhuǎn)換失敗的時(shí)候也不會(huì)出現(xiàn)錯(cuò)誤,所以對(duì)于如果能確保100%會(huì)成功的轉(zhuǎn)換則可使用 as!,否則使用 as?

let animal1:Animal = Cat()
if let cat = animal1 as? Cat{

    print("as? --- \(cat)")
}else{

    print("cat is nil")
}

類型轉(zhuǎn)換as操作符結(jié)果輸出

代碼已上傳至git:
--> 傳送門:Swift_基本語法

附錄

查看完整專欄《Swift學(xué)習(xí)》

有問題歡迎指正以及相互探討 —— CoderSun

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容