swift 学习- 21 -- 类型转换

// 类型转换 可以判断实例的类型, 也可以将实例看做其父类的或者子类的实例

// 类型转换在 Swift 中使用 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, aritist: String) {

self.artist = aritist

super.init(name: name)

}

}

let library = [

Movie.init(name: "Casablanca", director: "Michael Curtiz"),

Song.init(name: "Blue Suede Shoes", aritist: "Elvis Presley"),

Movie.init(name: "Citizen Kane", director: "Orson Welles"),

Song.init(name: "The One And Only", aritist: "Chesney Hawkes"),

Song.init(name: "Never Gonna Give You Up", aritist: "Rick Astley")

]

// 类型检查

// 用类型检查符 ( 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")

// 向下转型

// 某类型的一个常量 或 变量可能在幕后属于一个子类, 当确定是这种情况时, 你可以尝试向下转到它的子类型, 用类型转换 操作符 (as? 或 as)

// 因为向下转型 可能会失败 ,类型转换操作符带有两个不同的形式, 条件形式 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)")

}

}

// 转换没有真的改变实例它的值, 根本的实例保持不变, 只是简单的把它作为它被转换成的类型来使用

// Any 和 AnyObject 的类型转换

// Swift为不确定的类型提供了两个特殊的了类型别名

// Any 可以表示 任何类型, 包括函数类型

// AnyObject 可以表示任何 类类型 的实例

// 只有当你确实需要它们的行为和功能是才使用 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)" })

// 注意 : Any 类型可以表示所有类型的值, 包括可选类型, Swift 会在你用 Any 类型来表示一个可选值的时候, 给你一个警告, 如果你确实想使用 Any 类型来承载可选值, 你可以使用 as 操作符显式转换为 Any

let optionalNumber: Int? = 3

things.append(optionalNumber) // 警告

things.append(optionalNumber as Any) // 没有警告