Swift
类型转换
本文详细介绍了 Swift 中的类型转换,包括使用 is 检查类型、使用 as? 和 as! 进行向下转型,以及 Any 和 AnyObject 的使用。
类型转换(Type Casting)用于检查实例的类型,或者将实例作为其类层次结构中的不同超类或子类来处理。在 Swift 中,类型转换使用 is 和 as 操作符实现。
定义类层次结构
为了演示类型转换,我们定义一个基类 MediaItem 和两个子类 Movie 和 Song。
class MediaItem {
var name: String
init(name: String) {
self.name = name
}
}
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)
}
}
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")
]
// library 的类型被推断为 [MediaItem]检查类型 (Checking Type)
使用类型检查操作符 is 来检查一个实例是否属于特定子类。
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"向下转型 (Downcasting)
某类型的常量或变量可能实际上属于一个子类。你可以尝试使用类型转换操作符 as? 或 as! 将其向下转型为子类类型。
as?:返回一个可选值,当转型失败时返回nil。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)")
}
}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")
}
}在 GitHub 上编辑
上次更新于