- 檢查實例的類型录别;
- 將實例看作其自身類層次結構中其他不同的超類或子類;
- 類型轉換可以檢查類型是否符合某協(xié)議嘿悬;
- Swift中的類型轉換用
is
和as
操作符來實現低零;
1. 定義類型轉換的類層次結構
可以使用具有類和子類層次結構的類型轉換來檢查特定類實例的類型婆翔,并將該實例轉換到相同層次結構中的另一個類。
定義一個基類MediaItem
:
class MediaItem {
var name: String
init(name: String) {
self.name = name
}
}
定義基類MediaItem
的兩個子類---Movie
和Song
:
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.Any
和AnyObject
的類型轉換
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