Swift类型转换–as, is, Any, AnyObject

时间:2020-02-23 14:44:05  来源:igfitidea点击:

在本教程中,我们将研究Swift类型转换的详细信息。

什么是Swift类型转换?

广义上讲,类型转换由两部分组成:

  • 类型检查

  • 改变类型

  • " is"运算符用于检查实例的类型。

  • as运算符用于将实例转换为其他类型。

Swift类型检查

Swift对代码的可读性给予了很多优先考虑。
难怪要检查实例是否属于某种类型,我们使用is关键字。

例如,以下代码片段将始终显示false。

var isString = Int.self is String 
print(isString) //false

让我们在类及其子类中进行类型检查。
为此,我们创建了以下三个类。

class University
{
  var university: String
  init(university: String) {
      self.university = university
  }
}

class Discipline : University{
  var discipline: String
  init(university: String, discipline: String) {
      self.discipline = discipline
      super.init(university: university)
  }
}

class Student : University{
  var student: String
  init(student: String, university: String) {
      self.student = student
      super.init(university: university)
  }
}

在以下各节中,我们将介绍上播和下播。

Swift向上转换(Upcasting)

让我们为每个类创建一个对象,并将它们组合成一个数组。
我们的目标是了解您的类型!

var array = [University(university: "MIT"),Discipline(university: "IIT",discipline: "Computer Science"),Student(student: "Anupam",university: "BITS")]

print(array is [Student])
print(array is [Discipline])
print(array is [University])

该数组是University类型。
所有子类始终隐式地上载到父类。

在上面的代码中,Swift类型检查器会自动确定这些类的公共超类并将其设置为类型。

type(of :)可以用来确定任何变量/常量的类型。

var university = University(university: "MIT")
var student = Student(student: "Anupam",university: "BITS")
var discipline = Discipline(university: "IIT",discipline: "Computer Science")

print(student is University) //true
print(discipline is University) //true
print(university is Student) //false
print(university is Discipline) //false

协议是类型。
因此,类型检查和强制转换在它们上的工作方式相同。

以下代码显示为true。

protocol SomeProtocol {
  init(str: String)
  
}

class SomeClass : SomeProtocol {
  required init(str: String) {
  }
}

var sc = SomeClass(str: "theitroad.local")
print(sc is SomeProtocol) //true

Swift向下转换(Downcasting)

为了将超类向下转换为子类,我们使用运算符as

  • as具有两个变体,即as和as,用于处理向下转换失败时的情况。

  • 通常用于基本转化。

  • 如果向下转换成功,则" as?"将返回一个可选值,否则将返回nil。

  • as as!力解开了价值。
    仅在绝对确定向下转换不会失败时才应使用。
    否则,将导致运行时崩溃。

//Double to float
let floatValue = 2.35661312312312 as Float
print(float) //prints 2.35661

let compilerError = 0.0 as Int //compiler error
let crashes = 0.0 as! Int //runtime crash

让我们再次看一看类的层次结构。
现在,让我们尝试将数组元素转换为子类类型。

var array = [University(university: "MIT"),
           Discipline(university: "IIT",discipline: "Computer Science"),
           Student(student: "Anupam",university: "BITS"),
           Student(student: "Mark",university: "MIT")]

for item in array {
  if let obj = item as? Student {
      print("Students Detail: \(obj.student), \(obj.university)")
  } else if let obj = item as? Discipline {
      print("Discipline Details: \(obj.discipline), \(obj.university)")
  }
}

我们将大学类型简化为子类类型。
以下结果将打印在控制台中。

我们使用if语句优雅地解开可选部分。

Any和AnyObject

根据Apple Docs:

<p>Any can represent an instance of any type at all, including function types.<br 
AnyObject can represent an instance of any class type.</p>

AnyObject可以是Any类型的一部分。
在AnyObject数组内部,要设置值类型,我们需要使用" as"运算符将其类型转换为AnyObject。

class A{
  var a = "Anupam"
}
func hello()
{
  print("Hello")
}

var anyType : [Any] = [1, "Hey",array,true, 1.25, A(), hello()]
var anyObjectType : [AnyObject] = [A(),array as AnyObject, 1 as AnyObject,"Hey" as AnyObject]

print(anyType)
print(anyObjectType)

for item in anyType {
  if let obj = item as? A {
      print("Class A property name is: \(obj.a)")
  }
}

for item in anyObjectType {
      if let obj = item as? String {
          print("String type: \(type(of: obj))")
      }
}

存在于anyType数组中的函数会打印在该数组的声明中。

注意,对于anyObjectType,该字符串在打印时不带双引号。

此外,AnyObject仅允许对象类型。
字符串和整数是值类型。

那怎么运作呢?

在将字符串和int转换为AnyObject时,它们都将转换为非值类型的NSString和NSNumber类类型。
因此,只要我们正确使用as运算符,就可以在AnyObject中设置String,Int。