寒城攻略:Listo 教你 25 天学会 Swift 语言 - 20 Type Casting

时间:2022-01-14 21:12:48

import Foundation


//***********************************************************************************************

//1.Type Casting(类型转换)

//_______________________________________________________________________________________________

//介绍

//类型转化是一种检查实例的方式,类型转化在 Swift 使用 is as 操作符来实现,这两个操作符提供了一种简单的表达意思的方式去检查值的类型或者转换值的类型


//***********************************************************************************************

//2.Defining a Class Hierarchy for Type Casting(定义一个类层次作为例子)

//_______________________________________________________________________________________________

//介绍

//我们用它在类和子类的层次结构上,检查特定类的实例的类型并且转换这个类实例的类型成为这个层次结构中的其他类型


//_______________________________________________________________________________________________

//实例代码演示类层次的类型转化

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 = [                        //创建数组存储类实例,在幕后 library 里存储的项依然是 Movie Song 类型的,但是,若你迭代它, Swift会自动识别 Movie 类和 Song 类有共同的父类 MediaItem类,所以取出的实例会是 MediaItem类型的,而不是 Movie Song 类型的。为了让它们作为它们本来的 类型工作,你需要检查它们的类型或者向下转换它们的类型到其它类型

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

Song(name: " BlueSuede 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")

]


//***********************************************************************************************

//3.Checking Type(检查类型)

//_______________________________________________________________________________________________

//实例代码演示检查类型(用类型检查操作符(is)来检查一个实例是否属于特定子类型。类型检查操作符返回 true 实例属于那个子类型,若不属于返回 false

var movieCount =0

var songCount =0

for itemin library{

   if item is Movie{               //使用 is来检查类型

        ++movieCount

    }

   else if itemis Song{

        ++songCount

    }

}

println("Media library contains\(movieCount) movies and\(songCount) songs")


//***********************************************************************************************

//4.Downcasting(向下转型(简称下转)

//_______________________________________________________________________________________________

//某类型的一个常量或变量可能在幕后实际上属于一个子类。你可以相信,上面就是这种情况。你可以尝试向下转到它的子类型,用类型转换操作符(as)

//如果不确定下转一定成功,使用 as的可选类型 as


//_______________________________________________________________________________________________

//实例代码演示下转类型

for itemin library{

    iflet movie = itemas? Movie{             //试图用 as? 来将 item MediaItem 类下转为 Movie 类,他可能为 Movie 类,也可能为 Song 类,或者仅仅为 MediaItem类的实例,因为不确定,使用 as? 来试图下转返回一个可选值 Movie?

       println("Movie: '\(movie.name)', dir.\(movie.director)")

    }

   else if let song = item as? Song{

       println("Song: '\(song.name)', by\(song.artist)")

    }

}


//***********************************************************************************************

//5.Type Casting for Any and AnyObject(Any AnyObject 的转换)

//_______________________________________________________________________________________________

//介绍

//Swift 为不确定类型提供了两种特殊类型别名:1.AnyObject可以代表任何 class 类型实例;2.Any可以表示任何类型,包括非 class 类型,除了方法类型



//_______________________________________________________________________________________________

//AnyObject类型代码演示

let someObjects: [AnyObject] = [       //定义 AnyObject 类型的数组并且包含三个元素(只能为 class 类型的元素)

    Movie(name:"2001: A Space Odyssey", director: "Stanley Kubrick"),

   Movie(name: "Moon", director:"Duncan Jones"),

   Movie(name: "Alien", director:"Ridley Scott")

]


for object in someObjects{

   let movie = object as Movie

   println("Movie: '\(movie.name)', dir.\(movie.director)")

}


//_______________________________________________________________________________________________

//Any 类型代码演示

var things = [Any]()       //创建混合类型数据一起工作的数组 things,包含非 class类型

things.append(0)

things.append(0.0)

things.append(42)

things.append(3.14159)

things.append("hello")

things.append(Movie(name:"Ghostvusters", director: "Ivan Reitman"))


for thing inthings{           //使用 switch 来灵活应用 is as

   switch thing{

   case 0.0 as Int:

        println("zero as an Int")

   case 0 as Double:

        println("zero as a Double")

   case let someIntas Int:

        println("an integer value of\(someInt)")

   case let someDoubleas Double where someDouble > 0:

        println("a positive double value of\(someDouble)")

   case is Double:

        println("some other double value that I don't want to print")

   case let someStringas String:

        println("a string value of \"\(someString)\"")

   case let (x, y)as (Double,Double):

        println("an (x, y) point at\(x), \(y)")

   case let movieas Movie:

       println("a movie called '\(movie.name)', dir.\(movie.director )")

    default:

        println("something else")

    }

}