//类型转换
/*
1.类型转换可以判断实例的类型,也可以将该实例在其所在的类层次中视为其父类或子类的实例。
2.Swift 中类型转换的实现为 is 和 as 操作符。这两个操作符使用了一种简单传神的方式来检查一个值的类型或将某个值转换为另一种类型。
3.如同协议实现的检查(此处应有链接)中描述的那样,你还可以使用类型转换来检查类型是否遵循某个协议
*/
//为类型转换定义类层次 你可以在类及其子类层次中使用类型转换来判断特定类实例的类型并且在同一类层次中将该实例类型转换为另一个类。
class MediaItem {
//基类
var name:String
init(name:String) {
self.name = name
}
}
class Movie: MediaItem {
//子类
var director: String
init(name:String, dic:String) {
director = dic
super.init(name: name)
}
}
class Song: MediaItem {
var artist: String
init(name:String,art:String) {
artist = art
super.init(name: name)
}
}
//如果你遍历这个数组的内容,你取出的项目将会是 MediaItem 类型而非 Movie 或 Song 类型
let libary = [Movie(name: "Casablanca",dic: "Orson Welles"), Song(name: "Blue Suede Shoes", art: "Elvis Presley"),Movie(name: "Citizen Kane", dic: "Orson Welles"),Song(name: "The One And Only", art: "Chesney Hawkes"),Song(name: "Never Gonna Give You Up", art: "Rick Astley")]
//类型检查 使用类型检查操作符 ( is )来检查一个实例是否属于一个特定的子类。如果实例是该子类类型,类型检查操作符返回 true ,否则返回 false
var movieCount:Int = 0
var songCount:Int = 0
for item in libary{
if item is Movie{
movieCount += 1
}else if item is Song{
songCount += 1
}
}
print("movie is (movieCount) song is (songCount)")
//向下类型转换 某个类类型的常量或变量可能实际上在后台引用自一个子类的实例。当你遇到这种情况时你可以尝试使用类型转换操作符( as? 或 as! )将它向下类型转换至其子类类型。由于向下类型转换能失败,类型转换操作符就有了两个不同形式。条件形式, as? ,返回了一个你将要向下类型转换的值的可选项。强制形式, as! ,则将向下类型转换和强制展开结合为一个步骤。如果你不确定你向下转换类型是否能够成功,请使用条件形式的类型转换操作符 ( as? )。使用条件形式的类型转换操作符总是返回一个可选项,如果向下转换失败,可选值为 nil 。这允许你检查向下类型转换是否成功。当你确信向下转换类型会成功时,使用强制形式的类型转换操作符( as! )。当你向下转换至一个错误的类型时,强制形式的类型转换操作符会触发一个运行错误。
for item in libary{
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)")
}
}
//Swift 为不确定的类型提供了两种特殊的类型别名:
// - AnyObject 可以表示任何类类型的实例。
// - Any 可以表示任何类型,包括函数类型。
let someMovie:[AnyObject] = [Movie(name: "2001: A Space Odyssey", dic: "Stanley Kubrick"),
Movie(name: "Moon", dic: "Duncan Jones"),
Movie(name: "Alien", dic: "Ridley Scott")]
for object in someMovie{
let movie = object as! Movie
print("Movie: '(movie.name)', dir. (movie.director)")
}
for movie in someMovie as! [Movie]{
}
//使用 Any 类型来对不同类型进行操作,包含了函数类型以及非类类型
var things = [Any]()
things.append(0.0)
things.append("hello")
things.append((3.0,5.0))
things.append(Movie(name:"sss",dic: "sss"))
things.append({(name:String) -> String in "hello,(name)"})
for thing in things {
switch thing{
case 0 as Int:
print("zero as an Int")
case let someInt as Int:
print("an integer value of (someInt)")
case is Movie:
print("(thing) is movie")
case let something as String:
print("(something) is string")
case let (x,y) as (Int,Int):
print("an (x, y) point at (x), (y)")
case let stringConverter as (String) -> String:
print(stringConverter("Michael"))
default:
print("something else")
}
}
//
/*
1.枚举通常用于实现特定类或结构体的功能。类似的,它也可以在更加复杂的类型环境中方便的定义通用类和结构体。为实现这种功能,Swift 允许你定义内嵌类型,借此在支持类型的定义中嵌套枚举、类、或结构体。
2.若要在一种类型中嵌套另一种类型,在其支持类型的大括号内定义即可。可以根据需求多级嵌套数个类型。
*/
struct BlackjackCard {
enum Suit:Character {
case Spades = "♠", Hearts = "♡", Diamonds = "♢", Clubs = "♣"
}
enum Rank:Int {
case Two = 2, Three, Four, Five, Six, Seven, Eight, Nine, Ten
case Jack, Queen, King, Ace
struct Values {
let frist:Int , second:Int?
}
var values:Values{
switch self {
case .Ace:
return Values(frist: 1,second: 11)
case.Jack, .Queen, .King:
return Values(frist: 10, second: nil)
default:
return Values(frist: self.rawValue, second: nil)
}
}
}
let rank:Rank,suit:Suit
var description:String{
var output = "suit is (suit.rawValue),"
output += " value is (rank.values.frist)"
if let second = rank.values.second {
output += " or (second)"
}
return output
}
}
let theAceOfSpades = BlackjackCard(rank: .Ace,suit: .Spades)
print("theAceOfSpades: (theAceOfSpades.description)")
//引用内嵌类型
//要在定义外部使用内嵌类型,只需在其前缀加上内嵌了它的类的类型名即可:
let heartsSymbol = BlackjackCard.Suit.Hearts.rawValue