Swift类型转换–as, is, Any, AnyObject
在本教程中,我们将研究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。