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。

