Swift中的类型铸造

由苹果公司在2014年创建的Swift是一种流行的开源语言,用于构建iOS应用程序,已经获得了一个强大的开发者社区和丰富的第三方内容。

像其他几乎所有的编程语言一样,Swift有自己的规则和语法。在本指南中,我们将看看Swift中的类型转换,这是现代面向对象编程语言中的一个流行概念。

什么是Swift中的类型?

从本质上讲,类型是类的原始等价物,用于表示存储在变量中的数据种类。由于每个类都与其他类不同,所以数据类型也不同,允许开发人员根据它们持有的数据类型来区分变量。对数据类型进行分类可以防止类型不匹配,这是编译时的一个常见错误。

对于编译器来说,类型是不相关的。如果存储在一个变量中的数据符合在流程中稍后进行的操作,进程将相应地运行。

然而,如果类型不匹配导致流程中断,你会看到一个编译错误。即使类型不匹配没有明确地破坏流程,它也可能在编译过程中没有被注意到,导致程序运行时出现意想不到的结果。

Swift是一种强类型的编程语言。Swift中的每个变量都有一个与之相关的类型,一旦一个类型被分配给一个变量,它就不能存储任何其他类型的数据。

弱类型语言在这方面没有那么严格。例如,在PHP和C等语言中,你可以在一定程度上改变数据类型,以获得代码的更大灵活性。

什么是类型转换?

使用类型的限制迫使一种语言失去了很大一部分的灵活性。类型转换提供了一种方法来获得一些灵活性。

并非所有的类变量都持有像整数和字符串这样的原始数据。现代应用程序的大部分逻辑都依赖于自定义对象,而这些对象是通过类实现的。从现在开始,我们将用类型来指代原始数据类型和类。

类型转换是大多数面向对象语言中使用的一种编程范式,它允许开发者把一种类型的对象当作另一种类型的对象。虽然类型转换一开始可能没有什么意义,但它有助于简化现代应用程序中的许多程序。

类型转换并不改变相关的对象。相反,它改变了用于描述该对象的类型。例如,你显然不能把一个持有字符串的对象的类型从string 改为integer ,因为在现实生活中,把一个句子当作一个数字是没有意义的。

为了使类型转换发生,相关对象的原始类型和新类型必须是彼此的子类或超类。假设一个叫做Vehicle 的类有两个子类,CarTruck 。你可以把一个类型为Car 的对象投给Vehicle ,反之亦然;或者把Truck 投给Vehicle ,反之亦然。

现在,我们假设有另一个叫做Ship 的类,它与TruckCarVehicle 没有关系。你将不能把它的对象投到上面给出的任何类型中。

上投

上投是用来通过使用一个类本身的变量来概括该类的一系列子类的。让我们考虑一下使用Car,Truck, 和Vehicle 的例子。

我们在前面提到,CarTruck 可以被类型转换为Vehicle 。一个子类的对象被类型转换为其超类的对象。可以把它看作是在类的层次结构中向上移动。

上投允许你将任何类型的Vehicle 存储在一个类型为Vehicle 的引用中:Car,Truck, 等等。我们已经知道,这些都是同一个类的后代,Vehicle ,而且它们必然有一些相似之处。将它们的对象上传到Vehicle 类中,使用了这种泛化,让我们使用循环和其他常规范式运行操作。

下面是一个上传法的例子。

let truck:Truck = Vehicle(wheels:8)
复制代码

在上面的代码块中,你声明了一个名为truck 的引用,它的类型是Truck 。接下来,你用一个Vehicle 的实例来初始化它,它有八个轮子。你可以看到引用变量的类型注释和分配给它的对象是完全不同的。

如前所述,我们可以执行这个操作,因为TruckVehicle 属于同一个类的层次结构。这完全就像说卡车是车辆一样,在逻辑上是正确的。

在上面的例子中,上播是隐含的。然而,你可以通过运行下面的代码使其可见。

let truck:Truck = Vehicle(wheels:8) as Truck
复制代码

稍后,我们将更详细地介绍隐式上播。

下传

下投是与上投相反的,它指的是将一个父类类型的对象投给其子类的对象。下投是用来重新转换先前被上投的子类对象,以实现泛化。

比方说,你拥有两辆汽车和三辆卡车。如果你把它们存储在一个共享数组中,类型推理将决定数组的类型为Vehicle ,这是两个类型的共同父类。

如果你试图从数组中获取一个项目,你会得到一个类型为Vehicle 的对象。要把它变回原来的类型,你需要把它下移到一个TruckVehicle

必须了解的是,列表中的车辆并非都是汽车,这可能会在某些情况下导致下转换的失败。为了解决这个问题,我们将使用两种类型的下划线操作符,我们将在后面介绍。

水平类型转换

请注意,CarTruck 有一个共同的超类,但是,你不能把一个类型为Car 的对象投到Truck ,反之亦然。它们既不是彼此的子类也不是彼此的超类。因此,水平铸造是无效的,如果你试图将一个Car 铸造到一个Truck ,你会得到一个错误。

Swift中的类型转换操作

为了执行上述操作,你将使用以下运算符。

as

as 运算符被用来上投对象。然而,在大多数情况下,上投是以隐式方式进行的,所以你不会经常使用as

重申一下,这里有一个将Chair 上传到Furniture 的例子。

let furniture:Furniture = Chair(legs: 4) as Furniture
复制代码

as?

as? 操作符用于可选的下移,是Swift中可用的两个下移操作符之一。当你不确定一个对象是否能被成功下传时,请使用as?

如果你试图从一个不同的类层次结构中下移一个对象,你的程序在遇到错误时就会返回一个nil 值。为了验证下转换是否成功,你可以把一个简单的检查nil

你可以在我们的Vehicle 例子中使用as? 操作符。

let truckObject = vehiclesArray[0] as? Truck
复制代码

你指示控件访问数组中的第一个对象,将其下传到一个Truck ,并将结果存储在truckObject 变量中。

如果下移成功,你会在truckObject 中找到一个Truck 实例。如果失败,truckObject 将指向nil 。然后你可以通过运行来检查nil

if truckObject != nil {
print("The reference points to some value!")
} else {
print("The reference points to nil, and so the downcast was unsuccessful")
}
复制代码

as!

as! 操作符用于强制下转换,它只在类型转换操作可能时返回一个对象。如果你试图从不同的类层次结构中下移一个对象,你的程序将遇到一个致命的错误。

下面是你如何使用as! 操作符与我们的Vehicle 例子。

let carObject = vehiclesArray[1] as! Car
复制代码

上面这行代码是指示控件从数组中访问第二个对象,将其下移到一个Truck ,并将结果存储在truckObject 变量中。如果下转换失败,程序就会崩溃。

考虑到以上几点,只有当你确定你要下传的对象属于类的层次结构时,你才应该使用as! 操作符,并且操作会成功完成。

你也可以在以下情况下使用as! 操作符:如果类型不匹配,代码的流程需要中断,这表明在中间计算中可能会有意外的结果。

is

is 操作符用于检查一个实例的类型。使用is 操作符进行类型检查的结果是Bool ,它表示类型是否匹配,如下面的代码块所示。

let car: Car = Car(wheels: 4)

if car is Car {
print("It is a Car.")
} else if car is Truck {
print("It is a Truck.")
}
复制代码

输出结果是。

It is a Car.
复制代码

你也可以使用is 操作符来检查任何隐含的上播。让我们考虑一个例子。

let car: Car = Vehicle(wheels: 4)

print(car is Car)
print(car is Truck)
print(car is Vehicle)
复制代码

上面的代码的输出是:。

true
false
true
复制代码

输出结果表明,汽车引用的类型是Car ,隐式上播的类型是Vehicle 。由于水平投射是不可能的,Car 不可能属于Truck

自己尝试一下

在这篇文章中,你了解了Swift中的类型和类型投射,并涵盖了用于类型投射对象的各种操作符。

类型转换是一个概念,它使面向对象的编程非常强大和灵活。由于能够通过上投和下投在类的层次结构中上下移动,你可以根据需要利用泛化。

保留所有信息的关键是要不断练习。我希望你喜欢这篇文章。编码愉快

The postType casting in Swift appeared first onLogRocket Blog.

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享