【Swift 3.1】19 - 類型轉(zhuǎn)換 (Type Casting)

【Swift 3.1】19 - 類型轉(zhuǎn)換 (Type Casting)

自從蘋果2014年發(fā)布Swift,到現(xiàn)在已經(jīng)兩年多了,而Swift也來到了3.1版本。去年利用工作之余,共花了兩個多月的時間把官方的Swift編程指南看完。現(xiàn)在整理一下筆記,回顧一下以前的知識。有需要的同學(xué)可以去看官方文檔>>


類型轉(zhuǎn)換是用來檢查實(shí)例的類型,或在繼承鏈中把實(shí)例作為不同的父類或子類的一種方法。

Swift中的類型轉(zhuǎn)換用isas來實(shí)現(xiàn)。

為類型轉(zhuǎn)換定義一個類的層次結(jié)構(gòu) (Defining a Class Hierarchy for Type Casting)

第一個類是MediaItem。假設(shè)所有的媒體項目,包括電影和音樂,并且有名字:

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

第二個類是MediaItem的子類Movie。第三個也是MediaItem的子類:

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)
    }
}

最后創(chuàng)建了一個library數(shù)組,包含了兩個Movie實(shí)例和三個Song實(shí)例。Swift根據(jù)字面值推斷出library[MediaItem]類型:

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")
]
// the type of "library" is inferred to be [MediaItem]

雖然這個數(shù)組裝的是MovieSong實(shí)例,但如果遍歷這個數(shù)組,取出來的元素是MediaItem類型,而不是MovieSong類型。為了使用他們的真實(shí)類型,我們需要檢查他們的類型,或者向下轉(zhuǎn)型。

檢查類型 (Checking Type)

使用is來檢查一個實(shí)例是否是一個子類類型。如果是一個子類類型,返回true,否則返回false

var movieCount = 0
var songCount = 0

for item in library {
    if item is Movie {
        movieCount += 1
    }
    else if item is Song {
        songCount += 1
    }
}

print("Media library contains \(movieCount) movies and \(songCount) songs")
// Prints "Media library contains 2 movies and 3 songs"

向下轉(zhuǎn)型 (Downcasting)

一個類型的常量或變量實(shí)際上可能是子類的實(shí)例類型,我們可以使用as?或者as!來向下轉(zhuǎn)型到子類類型。

因為向下轉(zhuǎn)型可能會失敗,所以轉(zhuǎn)型運(yùn)算符有兩種類型。as?返回你想轉(zhuǎn)到的那個類型的可選類型;而as!如果轉(zhuǎn)型成功,返回你想轉(zhuǎn)到的那個類型,轉(zhuǎn)型失敗將會報錯。

如果不確定是否能轉(zhuǎn)型成功,使用as?;如果能確定轉(zhuǎn)型成功,使用as!

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)")
    }   
}

注意:轉(zhuǎn)型實(shí)際上不會修改實(shí)例或者改變它的值,在底層中,還是同一個實(shí)例。

Any和AnyObject的類型轉(zhuǎn)換 (Type Casting for Any and AnyObject)

Swift提供了兩種不確定的類型:

  • Any可以代表任何類型的實(shí)例,包括方法類型
  • AnyObject代表任何class類型的實(shí)例

下面是一個例子:

var things = [Any]()
 
things.append(0)
things.append(0.0)
things.append(42)
things.append(3.14159)
things.append("hello")
things.append((3.0, 5.0))
things.append(Movie(name: "Ghostbusters", director: "Ivan Reitman"))
things.append({ (name: String) -> String in "Hello, \(name)" })

向下轉(zhuǎn)型:

for thing in things {
    switch thing {
    case 0 as Int:
        print("zero as an Int")
    case 0 as Double:
        print("zero as a Double")
    case let someInt as Int:
        print("an integer value of \(someInt)")
    case let someDouble as Double where someDouble > 0:
        print("a positive double value of \(someDouble)")
    case is Double:
        print("some other double value that I don't want to print")
    case let someString as String:
        print("a string value of \"\(someString)\"")
    case let (x, y) as (Double, Double):
        print("an (x, y) point at \(x), \(y)")
    case let movie as Movie:
        print("a movie called \(movie.name), dir. \(movie.director)")
    case let stringConverter as (String) -> String:
        print(stringConverter("Michael"))
    default:
        print("something else")
    }
}
 
// zero as an Int
// zero as a Double
// an integer value of 42
// a positive double value of 3.14159
// a string value of "hello"
// an (x, y) point at 3.0, 5.0
// a movie called Ghostbusters, dir. Ivan Reitman
// Hello, Michael

注意: Any代表任何類型的值,包括可選類型。如果在需要傳入Any類型的位置傳入一個可選類型的值,Swift會給你一個警告。如果確實(shí)需要把可選類型的值作為一個Any類型的值,可以使用as來明確地轉(zhuǎn)為Any類型:

let optionalNumber: Int? = 3
things.append(optionalNumber)        // Warning
things.append(optionalNumber as Any) // No warning

第十九部分完。下個部分:【Swift 3.1】20 - 嵌套類型 (Nested Types)


如果有錯誤的地方,歡迎指正!謝謝!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,622評論 6 544
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,716評論 3 429
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,746評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,991評論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 72,706評論 6 413
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 56,036評論 1 329
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,029評論 3 450
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 43,203評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,725評論 1 336
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 41,451評論 3 361
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,677評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,161評論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,857評論 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,266評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,606評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,407評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,643評論 2 380

推薦閱讀更多精彩內(nèi)容