Swift程式設計十九(型別轉換)

2021-09-24 15:44:02 字數 3765 閱讀 3895

型別轉換是一種檢查例項型別的方法,或者將該例項視為與其自己的類層次結構中的其他位置不同的超類或子類。

swift中的型別轉換是使用is和as運算子實現的。這兩個運算子提供了一種簡單而富有表現力的方法來檢查值的型別或將值轉換為其他型別。

還可以使用型別轉換來檢查型別是否符合協議,如檢查協議一致性中所述。

可以使用型別轉換來檢查特定類例項在類和子類的層次結構中的型別,並將該例項轉換為同一層次結構中的另乙個類。下面的三個**片段定義了類的層次結構和包含這些類的例項的陣列,用於型別轉換的示例。

第乙個片段定義了乙個名為mediaitem的新基類。此類為數字**庫中顯示的任何型別的專案提供基本功能。具體來說,它宣告了乙個string型別的屬性name和乙個初始化器。(假設所有**專案,包括所有電影和歌曲,都會有乙個名字。)

class mediaitem 

}

下乙個片段定義了兩個mediaitem子類。第乙個子類movie包含有關電影或電影的其他資訊。它在mediaitem基類的基礎上新增了乙個director屬性,並帶有相應的初始化程式。第二個子類song,在基類之上新增乙個artist屬性和初始值設定項:

class movie: mediaitem 

}class song: mediaitem

}

最後乙個片段建立乙個名為library的常量陣列,其中包含兩個movie例項和三個song例項。library通過使用陣列文字的內容初始化陣列來推斷陣列的型別。swift的型別檢查器能夠推導出movie和song具有乙個共同的超類mediaitem,因此它推斷出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")

]

用兩個movie例項和三個song例項建立library常量陣列。但是,如果迭代此陣列的內容,則收到的專案將被鍵入mediaitem,而不是movie或song。要將它們作為本型別使用,需要檢查其型別,或將它們向下轉換為其他型別,如下所述。

使用型別檢查運算子(is)來檢查例項是否屬於某個子類型別。如果例項屬於該子類型別,則型別檢查操作符返回true,如果不是,則返回false。

下面的例子定義兩個變數,moviecount和songcount,其計數library陣列中movie和song例項的數量:

var moviecount = 0

var songcount = 0

for item in library else if item is song

}print("media library contains \(moviecount) movies and \(songcount) songs")

此示例遍歷library陣列中的所有項。每次通過for-in迴圈將item常量設定為mediaitem陣列中的下乙個。

如果當前mediaitem是movie例項返回返回ture,如果不是,則返回false。同樣,檢查item是否為song例項。在for-in迴圈結束時,moviecount和songcount值表示含有各自型別計數的多少。

某個類型別的常量或變數實際上可能是子類的例項。在這種情況下,可以嘗試使用型別轉換運算子(as?或as!)向下轉換為子類型別。

由於向下轉換可能會失敗,因此型別轉換運算子有兩種不同的形式。條件形式as?,返回您嘗試向下轉換的型別的可選值。強制形式as!嘗試向下轉換並強制轉換結果。

當不確定向下轉換是否成功時,請使用型別轉換運算子(as?)的條件形式。這種形式的運算子將始終返回乙個可選值,如果無法進行向下轉換,則該值將為nil。這需要堅持轉換是否成功。

僅當確定向下轉換將始終成功時,才使用型別轉換運算子(as!)的強制形式。如果嘗試向下轉換為不正確的類型別,則此形式的運算子將觸發執行時錯誤。

下面的例子在library中迭代每個mediaitem,並列印每個專案的相應說明。要做到這一點,它需要將每個專案作為乙個真實movie或song,而不僅僅作為乙個mediaitem。這是為了能夠訪問movie的director屬性或song的artist屬性在說明中使用。

在此示例中,陣列中的每個項可能是movie,或者可能是song。事先並不知道每個專案使用哪個實際類,因此使用型別轉換(as?)的條件形式來檢查每次迴圈時的向下轉換為合適的operator:

for item in library  else if let song = item as? song 

}

該示例首先嘗試將當前item向下轉換為movie。因為item是乙個mediaitem例子,這是可能的,它可能是乙個movie; 同樣,它也可能是乙個song,甚至只是乙個mediaitem。由於這種不確定性,型別轉換運算子的形式as?在嘗試向下轉換為子類型別時返回乙個可選值。item as? movie結果是movie?型別或「optional movie」。

陣列中的movie例項轉換為song例項時,向下轉換失敗。為了解決這個問題,上面的示例使用可選繫結來檢查可選movie實際上是否包含乙個值(即,型別轉換是否成功。)此可選繫結寫為「if let movie = item as? movie」,可以讀作:

「嘗試轉換item為movie。如果成功,則設定乙個新的臨時常量儲存在返回的可選movie中。」

如果向下轉換成功,movie則使用屬性來列印該movie例項的描述,包括其名稱和導演。類似的原則用於檢查song例項,並在陣列中找到song時列印適當的描述(包括名稱和表演者)。

注意: 轉換實際上不會修改例項或更改其值。例項保持不變; 它被簡單地處理和訪問為它的型別的例項。

swift提供了兩種特殊型別來處理非特定型別:

使用any和anyobject只有當明確需要提供的的行為以及功能。最好轉化為在**中使用的型別。

以下是使用any不同型別混合的示例,包括函式型別和非類型別。該示例建立乙個名為things的any陣列,該陣列可以儲存任何型別的值:

var things = [any]()
things陣列包含兩個int值,兩個double值,乙個string值,乙個(double, double)型別的元組,電影「ghostbusters」,以及乙個帶有string值並返回另乙個string值的閉包表示式。

要把any或者anyobject型別轉換為特定型別的常量或變數,可以使用乙個is或as模式作為switch語句的情況。下面的示例遍歷things陣列中的專案,並使用switch語句查詢每個專案的型別。一些switch語句的情況將它們的匹配值繫結到指定型別的常量,以使其值可以列印:

for thing in things 

}

注意: any型別表示任何型別的值,包括可選型別。如果使用期望值為可選型別,swift會向發出警告any。如果確實需要使用可選值作為any值,則可以使用as運算子顯式地將可選值轉換為any,如下所示。

let optionalnumber: int? = 3

Swift 型別轉換

import uikit 1.定義基類 mediaitem 2.定義子類 movie 3.定義子類 song class mediaitem class movie mediaitem class song mediaitem let library movie name movie1 direct...

Swift中文教程(十九)型別巢狀

列舉型別常被用於實現特定類或結構體的功能。也能夠在有多種變數型別的環境中,方便地定義通用類或結構體來使用,為了實現這種功能,swift允許你定義型別巢狀,可以在列舉型別 類和結構體中定義支援巢狀的型別。要在乙個型別中巢狀另乙個型別,將需要巢狀的型別的定義寫在被巢狀型別的區域 內,而且可以根據需要定義...

swift 物件型別轉換

swift 中物件是可以轉換的,因為物件導向就會涉及繼承,子類,父類等等 有幾點規則我們先說一下 子類物件可以直接轉換為父類物件的 父類物件可以有條件的轉換為子類物件,這個我們下邊在講 首先我們建立三個類 人 homan 男人 man 男孩 boy man 繼承 homan boy 繼承 homan...