在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 教程/ iOS/ 類(lèi)型轉(zhuǎn)換
特性(Attributes)
Access Control 權(quán)限控制的黑與白
基本運(yùn)算符(Basic Operators)
基礎(chǔ)部分(The Basics)
閉包(Closures)
擴(kuò)展
泛型參數(shù)(Generic Parameters and Arguments)
訪(fǎng)問(wèn)控制和 protected
語(yǔ)句(Statements)
模式(Patterns)
WWDC 里面的那個(gè)“大炮打氣球”
關(guān)于語(yǔ)言參考(About the Language Reference)
語(yǔ)法總結(jié)(Summary of the Grammar)
嵌套類(lèi)型
類(lèi)型(Types)
Swift 初見(jiàn)(A Swift Tour)
泛型
枚舉(Enumerations)
高級(jí)運(yùn)算符
繼承
析構(gòu)過(guò)程
關(guān)于 Swift(About Swift)
訪(fǎng)問(wèn)控制
類(lèi)和結(jié)構(gòu)體
內(nèi)存安全
Swift 與 C 語(yǔ)言指針友好合作
協(xié)議
屬性(Properties)
可選類(lèi)型完美解決占位問(wèn)題
錯(cuò)誤處理
字符串和字符(Strings and Characters)
聲明(Declarations)
自動(dòng)引用計(jì)數(shù)
Swift 里的值類(lèi)型與引用類(lèi)型
表達(dá)式(Expressions)
Swift 文檔修訂歷史
造個(gè)類(lèi)型不是夢(mèng)-白話(huà) Swift 類(lèi)型創(chuàng)建
歡迎使用 Swift
詞法結(jié)構(gòu)(Lexical Structure)
集合類(lèi)型(Collection Types)
下標(biāo)
方法(Methods)
可選鏈?zhǔn)秸{(diào)用
版本兼容性
類(lèi)型轉(zhuǎn)換
構(gòu)造過(guò)程
The Swift Programming Language 中文版
函數(shù)(Functions)
Swift 教程
控制流(Control Flow)

類(lèi)型轉(zhuǎn)換


1.0 翻譯:xiehurricane 校對(duì):happyming

2.0 翻譯+校對(duì):yangsiy

2.1 校對(duì):shanks,2015-11-01

2.2 翻譯+校對(duì):SketchK 2016-05-16 3.0.1,shanks,2016-11-13

4.0 校對(duì):kemchenj 2017-09-21

4.1 翻譯+校對(duì):mylittleswift

本頁(yè)包含內(nèi)容:

類(lèi)型轉(zhuǎn)換可以判斷實(shí)例的類(lèi)型,也可以將實(shí)例看做是其父類(lèi)或者子類(lèi)的實(shí)例。

類(lèi)型轉(zhuǎn)換在 Swift 中使用 isas 操作符實(shí)現(xiàn)。這兩個(gè)操作符提供了一種簡(jiǎn)單達(dá)意的方式去檢查值的類(lèi)型或者轉(zhuǎn)換它的類(lèi)型。

你也可以用它來(lái)檢查一個(gè)類(lèi)型是否實(shí)現(xiàn)了某個(gè)協(xié)議,就像在檢驗(yàn)協(xié)議的一致性部分講述的一樣。

為類(lèi)型轉(zhuǎn)換定義類(lèi)層次

你可以將類(lèi)型轉(zhuǎn)換用在類(lèi)和子類(lèi)的層次結(jié)構(gòu)上,檢查特定類(lèi)實(shí)例的類(lèi)型并且轉(zhuǎn)換這個(gè)類(lèi)實(shí)例的類(lèi)型成為這個(gè)層次結(jié)構(gòu)中的其他類(lèi)型。下面的三個(gè)代碼段定義了一個(gè)類(lèi)層次和一個(gè)包含了這些類(lèi)實(shí)例的數(shù)組,作為類(lèi)型轉(zhuǎn)換的例子。

第一個(gè)代碼片段定義了一個(gè)新的基類(lèi) MediaItem。這個(gè)類(lèi)為任何出現(xiàn)在數(shù)字媒體庫(kù)的媒體項(xiàng)提供基礎(chǔ)功能。特別的,它聲明了一個(gè) String 類(lèi)型的 name 屬性,和一個(gè) init(name:) 初始化器。(假定所有的媒體項(xiàng)都有個(gè)名稱(chēng)。)

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

下一個(gè)代碼段定義了 MediaItem 的兩個(gè)子類(lèi)。第一個(gè)子類(lèi) Movie 封裝了與電影相關(guān)的額外信息,在父類(lèi)(或者說(shuō)基類(lèi))的基礎(chǔ)上增加了一個(gè) director(導(dǎo)演)屬性,和相應(yīng)的初始化器。第二個(gè)子類(lèi) Song,在父類(lèi)的基礎(chǔ)上增加了一個(gè) artist(藝術(shù)家)屬性,和相應(yīng)的初始化器:

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

最后一個(gè)代碼段創(chuàng)建了一個(gè)數(shù)組常量 library,包含兩個(gè) Movie 實(shí)例和三個(gè) Song 實(shí)例。library 的類(lèi)型是在它被初始化時(shí)根據(jù)它數(shù)組中所包含的內(nèi)容推斷來(lái)的。Swift 的類(lèi)型檢測(cè)器能夠推斷出 MovieSong 有共同的父類(lèi) MediaItem,所以它推斷出 [MediaItem] 類(lèi)作為 library 的類(lèi)型:

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")
]
// 數(shù)組 library 的類(lèi)型被推斷為 [MediaItem]

在幕后 library 里存儲(chǔ)的媒體項(xiàng)依然是 MovieSong 類(lèi)型的。但是,若你迭代它,依次取出的實(shí)例會(huì)是 MediaItem 類(lèi)型的,而不是 MovieSong 類(lèi)型。為了讓它們作為原本的類(lèi)型工作,你需要檢查它們的類(lèi)型或者向下轉(zhuǎn)換它們到其它類(lèi)型,就像下面描述的一樣。

檢查類(lèi)型

類(lèi)型檢查操作符is)來(lái)檢查一個(gè)實(shí)例是否屬于特定子類(lèi)型。若實(shí)例屬于那個(gè)子類(lèi)型,類(lèi)型檢查操作符返回 true,否則返回 false。

下面的例子定義了兩個(gè)變量,movieCountsongCount,用來(lái)計(jì)算數(shù)組 libraryMovieSong 類(lèi)型的實(shí)例數(shù)量:

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")
// 打印 “Media library contains 2 movies and 3 songs”

示例迭代了數(shù)組 library 中的所有項(xiàng)。每一次,for-in 循環(huán)設(shè)置 item 為數(shù)組中的下一個(gè) MediaItem。

若當(dāng)前 MediaItem 是一個(gè) Movie 類(lèi)型的實(shí)例,item is Movie 返回 true,否則返回 false。同樣的,item is Song 檢查 item 是否為 Song 類(lèi)型的實(shí)例。在循環(huán)結(jié)束后,movieCountsongCount 的值就是被找到的屬于各自類(lèi)型的實(shí)例的數(shù)量。

向下轉(zhuǎn)型

某類(lèi)型的一個(gè)常量或變量可能在幕后實(shí)際上屬于一個(gè)子類(lèi)。當(dāng)確定是這種情況時(shí),你可以嘗試向下轉(zhuǎn)到它的子類(lèi)型,用類(lèi)型轉(zhuǎn)換操作符as?as!)。

因?yàn)橄蛳罗D(zhuǎn)型可能會(huì)失敗,類(lèi)型轉(zhuǎn)型操作符帶有兩種不同形式。條件形式 as? 返回一個(gè)你試圖向下轉(zhuǎn)成的類(lèi)型的可選值。強(qiáng)制形式 as! 把試圖向下轉(zhuǎn)型和強(qiáng)制解包轉(zhuǎn)換結(jié)果結(jié)合為一個(gè)操作。

當(dāng)你不確定向下轉(zhuǎn)型可以成功時(shí),用類(lèi)型轉(zhuǎn)換的條件形式(as?)。條件形式的類(lèi)型轉(zhuǎn)換總是返回一個(gè)可選值,并且若下轉(zhuǎn)是不可能的,可選值將是 nil。這使你能夠檢查向下轉(zhuǎn)型是否成功。

只有你可以確定向下轉(zhuǎn)型一定會(huì)成功時(shí),才使用強(qiáng)制形式(as!)。當(dāng)你試圖向下轉(zhuǎn)型為一個(gè)不正確的類(lèi)型時(shí),強(qiáng)制形式的類(lèi)型轉(zhuǎn)換會(huì)觸發(fā)一個(gè)運(yùn)行時(shí)錯(cuò)誤。

下面的例子,迭代了 library 里的每一個(gè) MediaItem,并打印出適當(dāng)?shù)拿枋?。要這樣做,item 需要真正作為 MovieSong 的類(lèi)型來(lái)使用,而不僅僅是作為 MediaItem。為了能夠在描述中使用 MovieSongdirectorartist 屬性,這是必要的。

在這個(gè)示例中,數(shù)組中的每一個(gè) item 可能是 MovieSong。事前你不知道每個(gè) item 的真實(shí)類(lèi)型,所以這里使用條件形式的類(lèi)型轉(zhuǎn)換(as?)去檢查循環(huán)里的每次下轉(zhuǎn):

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

示例首先試圖將 item 下轉(zhuǎn)為 Movie。因?yàn)?item 是一個(gè) MediaItem 類(lèi)型的實(shí)例,它可能是一個(gè) Movie;同樣,它也可能是一個(gè) Song,或者僅僅是基類(lèi) MediaItem。因?yàn)椴淮_定,as? 形式在試圖下轉(zhuǎn)時(shí)將返回一個(gè)可選值。item as? Movie 的返回值是 Movie? 或者說(shuō)“可選 Movie”。

當(dāng)向下轉(zhuǎn)型為 Movie 應(yīng)用在兩個(gè) Song 實(shí)例時(shí)將會(huì)失敗。為了處理這種情況,上面的例子使用了可選綁定(optional binding)來(lái)檢查可選 Movie 真的包含一個(gè)值(這個(gè)是為了判斷下轉(zhuǎn)是否成功。)可選綁定是這樣寫(xiě)的“if let movie = item as? Movie”,可以這樣解讀:

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

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

注意

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

AnyAnyObject 的類(lèi)型轉(zhuǎn)換

Swift 為不確定類(lèi)型提供了兩種特殊的類(lèi)型別名:

  • Any 可以表示任何類(lèi)型,包括函數(shù)類(lèi)型。
  • AnyObject 可以表示任何類(lèi)類(lèi)型的實(shí)例。

只有當(dāng)你確實(shí)需要它們的行為和功能時(shí)才使用 AnyAnyObject。當(dāng)你期望你的代碼可以工作,最好還是要確定類(lèi)型。

這里有個(gè)示例,使用 Any 類(lèi)型來(lái)和混合的不同類(lèi)型一起工作,包括函數(shù)類(lèi)型和非類(lèi)類(lèi)型。它創(chuàng)建了一個(gè)可以存儲(chǔ) Any 類(lèi)型的數(shù)組 things

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

things 數(shù)組包含兩個(gè) Int 值,兩個(gè) Double 值,一個(gè) String 值,一個(gè)元組 (Double, Double),一個(gè) Movie 實(shí)例“Ghostbusters”,以及一個(gè)接受 String 值并返回另一個(gè) String 值的閉包表達(dá)式。

你可以在 switch 表達(dá)式的 case 中使用 isas 操作符來(lái)找出只知道是 AnyAnyObject 類(lèi)型的常量或變量的具體類(lèi)型。下面的示例迭代 things 數(shù)組中的每一項(xiàng),并用 switch 語(yǔ)句查找每一項(xiàng)的類(lèi)型。有幾個(gè) switch 語(yǔ)句的 case 綁定它們匹配到的值到一個(gè)指定類(lèi)型的常量,從而可以打印這些值:

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 類(lèi)型可以表示所有類(lèi)型的值,包括可選類(lèi)型。Swift 會(huì)在你用 Any 類(lèi)型來(lái)表示一個(gè)可選值的時(shí)候,給你一個(gè)警告。如果你確實(shí)想使用 Any 類(lèi)型來(lái)承載可選值,你可以使用 as 操作符顯式轉(zhuǎn)換為 Any,如下所示:

let optionalNumber: Int? = 3
things.append(optionalNumber)        // 警告
things.append(optionalNumber as Any) // 沒(méi)有警告
上一篇:構(gòu)造過(guò)程下一篇:協(xié)議