Swift18-类型转换

定义一个类型层次作为例子、检查类型、向下转换、Any和AnyObject的类型转换。

 

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

类型转换在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,artist:String){

    self.artist=artist

    super.init(name:name)

  }

}

let library=[Movie(name:"xyy",director:"cjj"), Song(name:"bkwzsyzy",artist:"cjj")]

//创建library数组时,包含了一个Movie实例和一个Song实例。数组的类型在它被初始化时推断出来。Swift的类型检测器能够推断出Movie和Song有相同的父类MediaItem,所以推断出[MediaItem]作为library的类型。

在幕后library里存储的项依然是Movie和Song类型。但是,若迭代它,依次取出的实例会是MediaItem类型的,而不是Movie和Song类型。为了让它们作为原本的类型工作,你需要检查它们的类型或者向下转换它们到其它类型。

 

检查类型:

用类型检查操作符(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

  }

}

 

向下转型:

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

因为向下转型可能会失败,类型转换操作符带有两种不同形式。条件形式as?返回一个试图向下转成的类型的可选值。

强制形式as!把试图向下转型和强制解包(转换结果)结合为一个操作。

条件形式的as?类型转换总是返回一个可选值,并且若下转是不可能的,可选值将是nil。这使得能够检查向下转型是否成功。

只有在确定向下转型一定会成功时,才使用强制形式(as!)。当试图向下转型为一个不正确的类型时,强制形式的类型转换会触发一个运行时错误。

 

 

Any和AnyObject的类型转换:

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

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

2)AnyObject可以表示任何类型的实例。

只有当确定需要它们的行为和功能时才使用Any和AnyObject。在你的代码里使用你期望的明确类型总是更好的。

 

var things=[Any]()

//创建了一个可以存储Any类型的数组things,它可以同时保存任何类型

 

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

 

let optionlNumber:Int?=3

things.append(optionalNumber)  //warning

things.append(optionalNumber as Any)

 

posted @ 2020-05-10 23:06  吉吉boy  阅读(147)  评论(0编辑  收藏  举报