类型转换可以判断实例的类型,也可以将实例看做是其父类或者子类的实例。
类型转换在 Swift中使用 is和 as操作符实现。这两个操作符提供了一种简单达意的方式去检查值的类型或者转换它的类型
is:检查值的类型
as:转换类型
*/
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 Curitiz"),
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")
]
/*用类型检查操作符(is)来检查一个实例是否属于特定子类型。若实例属于那个子类型,类型检查操作符返回 true,否则返回 false。
*/
var movieCount =0
var songCount =0
for item inlibrary {
if itemisMovie {
++movieCount
} elseif itemis Song {
++songCount
}
}
print("Media library contains\(movieCount) movies and\(songCount) songs")
//Media library contains 2 movies and 3 songs
某类型的一个常量或变量可能在幕后实际上属于一个子类。当确定是这种情况时,你可以尝试向下转到它的子类型,
用类型转换操作符(as?或 as!)
因为向下转型可能会失败,类型转型操作符带有两种不同形式。条件形式(conditional form) as?
返回一个你试图向下转成的类型的可选值(optional value)。强制形式 as!把试图向下转型和强制解包(force-unwraps)
结果作为一个混合动作。
当你不确定向下转型可以成功时,用类型转换的条件形式(as?)。条件形式的类型转换总是返回一个可选值(optional value),
并且若下转是不可能的,可选值将是 nil。这使你能够检查向下转型是否成功。
只有你可以确定向下转型一定会成功时,才使用强制形式(as!)。当你试图向下转型为一个不正确的类型时,
强制形式的类型转换会触发一个运行时错误。
总结:as?不确定, as! 确定
for iteminlibrary {
iflet movie = itemas?Movie {
print("Movie:\(movie.name), dir.\(movie.director)")
} elseiflet song = itemas?Song {
print("Song:\(song.name), by\(song.artist)")
}
}
//Movie: Casablanca, dir. Michael Curitiz
//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
/*Swift的两种不确定类型
1.Any:表示任何类型,包括方法类型
2.AnyObject:表示任何class类型的实例
*/
let someObjects: [AnyObject] = [
Movie(name:"2001: A Space odyssey", director:"Stanley kubrick"),
Movie(name:"moon", director:"Duncan Jones"),
Movie(name:"Alien", director:"Ridley Scott")
]
for objectinsomeObjects {
let movie = objectas! Movie
print("Movie:\(movie.name), dir.\(movie.director)")
}
//Movie: 2001: A Space odyssey, dir. Stanley kubrick
//Movie: moon, dir. Duncan Jones
//Movie: Alien, dir. Ridley Scott
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:"阿凡达", director:"RR"))
things.append({(name:String) ->Stringin "Hello, \(name)"})
for thinginthings {
switch thing {
case0as Int:
print("zero as an Int")
case0 as Double:
print("zero as a Double")
caselet someIntasInt:
print("an integer value of\(someInt)")
caselet someDoubleasDouble where someDouble >0:
print("a positive double value of\(someDouble)")
caseisDouble:
print("Some other double value that I don't want to print")
caselet someStringasString:
print("a string value of \"\(someString)\"")
caselet (x,y)as (Double,Double):
print("an (x, y) point at\(x),\(y)")
caselet movieasMovie:
print("a movie called '\(movie.name)', dir.\(movie.director)")
caselet stringConverterasString ->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 '阿凡达', dir. RR
//Hello, Michael