Swift 類型轉換詳解

  • 檢查實例的類型录别;
  • 將實例看作其自身類層次結構中其他不同的超類或子類;
  • 類型轉換可以檢查類型是否符合某協(xié)議嘿悬;
  • Swift中的類型轉換用isas操作符來實現低零;

1. 定義類型轉換的類層次結構

可以使用具有類和子類層次結構的類型轉換來檢查特定類實例的類型婆翔,并將該實例轉換到相同層次結構中的另一個類。
定義一個基類MediaItem:

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

定義基類MediaItem的兩個子類---MovieSong:

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

定義一個數組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]

2.檢測類型

使用類型檢查操作符is檢查實例是否屬于某個子類類型啃奴。如果實例屬于該子類類型,類型檢查操作符返回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"

3.類型轉換

某個類類型的常量或變量實際上可能引用子類的實例。這種情況下老厌,可以嘗試使用類型轉換操作符as ?as !瘟则。

  • as?返回要轉換類型的可選值;當不確定類轉換是否成功時枝秤,使用該條件類型轉換醋拧;
  • 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)")
    }
}

// Movie: Casablanca, dir. Michael Curtiz
// Song: Blue Suede Shoes, by Elvis Presley
// Movie: Citizen Kane, dir. Orson Welles
// Song: The One And Only, by Chesney Hawkes
// Song: Never Gonna Give You Up, by Rick Astley

強制類型轉換實際上并不會修改實例或更改其值薇溃。底層實例保持不變;它被簡單地當作一個已被轉換類型的實例來處理和訪問菌赖。

4.AnyAnyObject的類型轉換

Swift提供了兩種用于處理非特定類型的特殊類型:

  • Any 可以表示任何類型的實例,包括函數類型痊焊。
  • AnyObject 可以表示任何類類型的實例盏袄。
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)" })
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會產生警告。如果確實需要使用可選值作為任意值垄惧,那么可以使用as操作符將可選值顯式轉換為任意值刁愿,如下所示。
let optionalNumber: Int? = 3
things.append(optionalNumber)        // Warning
things.append(optionalNumber as Any) // No warning

5.其他專題模塊

Swift 4.2 基礎專題詳解

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末到逊,一起剝皮案震驚了整個濱河市铣口,隨后出現的幾起案子,更是在濱河造成了極大的恐慌觉壶,老刑警劉巖脑题,帶你破解...
    沈念sama閱讀 222,590評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現場離奇詭異铜靶,居然都是意外死亡叔遂,警方通過查閱死者的電腦和手機,發(fā)現死者居然都...
    沈念sama閱讀 95,157評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來已艰,“玉大人痊末,你說我怎么就攤上這事×ú簦” “怎么了凿叠?”我有些...
    開封第一講書人閱讀 169,301評論 0 362
  • 文/不壞的土叔 我叫張陵,是天一觀的道長嚼吞。 經常有香客問我盒件,道長,這世上最難降的妖魔是什么誊薄? 我笑而不...
    開封第一講書人閱讀 60,078評論 1 300
  • 正文 為了忘掉前任履恩,我火速辦了婚禮,結果婚禮上呢蔫,老公的妹妹穿的比我還像新娘切心。我一直安慰自己,他們只是感情好片吊,可當我...
    茶點故事閱讀 69,082評論 6 398
  • 文/花漫 我一把揭開白布绽昏。 她就那樣靜靜地躺著,像睡著了一般俏脊。 火紅的嫁衣襯著肌膚如雪全谤。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,682評論 1 312
  • 那天爷贫,我揣著相機與錄音认然,去河邊找鬼。 笑死漫萄,一個胖子當著我的面吹牛卷员,可吹牛的內容都是我干的。 我是一名探鬼主播腾务,決...
    沈念sama閱讀 41,155評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼毕骡,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了岩瘦?” 一聲冷哼從身側響起未巫,我...
    開封第一講書人閱讀 40,098評論 0 277
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎启昧,沒想到半個月后叙凡,有當地人在樹林里發(fā)現了一具尸體,經...
    沈念sama閱讀 46,638評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡密末,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 38,701評論 3 342
  • 正文 我和宋清朗相戀三年握爷,在試婚紗的時候發(fā)現自己被綠了宰啦。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,852評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡饼拍,死狀恐怖,靈堂內的尸體忽然破棺而出田炭,到底是詐尸還是另有隱情师抄,我是刑警寧澤,帶...
    沈念sama閱讀 36,520評論 5 351
  • 正文 年R本政府宣布教硫,位于F島的核電站叨吮,受9級特大地震影響,放射性物質發(fā)生泄漏瞬矩。R本人自食惡果不足惜茶鉴,卻給世界環(huán)境...
    茶點故事閱讀 42,181評論 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望景用。 院中可真熱鬧涵叮,春花似錦、人聲如沸伞插。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,674評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽媚污。三九已至舀瓢,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間耗美,已是汗流浹背京髓。 一陣腳步聲響...
    開封第一講書人閱讀 33,788評論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留商架,地道東北人堰怨。 一個月前我還...
    沈念sama閱讀 49,279評論 3 379
  • 正文 我出身青樓,卻偏偏與公主長得像甸私,于是被迫代替她去往敵國和親诚些。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,851評論 2 361

推薦閱讀更多精彩內容