Swift入门:扩展

2020-03-19 20:46:06 浏览数 (1)

扩展允许我们以一种非常干净的方式修改Swift的数据类型以添加新的功能——我们的新代码与现有代码没有区别。

让我们从一个扩展开始,它将一个扩展添加到一个整数。是的,我意识到的是+=1,我们从最简单的开始。首先,添加此整数:

代码语言:javascript复制
var myInt = 0

extension Int告诉 Swift 我们想为其Int结构体添加功能。我们也可以使用StringArray或者其他的的,但是Int是一个很好的简单的开始。

使用扩展程序后,其工作方式将变得清晰。将以下行放在扩展名的末尾:

代码语言:javascript复制
myInt.plusOne()

在playground上的输出中,您现在将在第一行看到0,在第二行看到1,因此调用plusOne()返回的数字符合预期。

该扩展名已添加到所有整数,因此您甚至可以这样 调用它:

代码语言:javascript复制
5.plusOne()

完成此操作后,您将在输出列中看到 6。

我们的扩展在其输入值上加1并将其返回给调用方,但不修改原始值。尝试输入以下内容:

代码语言:javascript复制
var myInt = 10
myInt.plusOne()
myInt

单独使用变量会告诉 playground 仅输出其值,因此在输出列中将看到10,然后是11,然后再次是10。这是原始值,plusOne()方法的返回值以及原始的未更改值。

为了进一步说明问题,让我们修改plusOne()方法,使其不返回任何内容,而是修改实例本身(即输入的整数)。

为了实现这一目标,您可能会认为我们需要执行以下操作:

代码语言:javascript复制
extension Int {
    func plusOne() {
        self  = 1
    }
}

这会删除返回值,因为我们现在不返回任何东西,并且它使用 =运算符将一个加到self上。但这是行不通的,实际上Xcode会给您一个令人难以理解的错误消息:“Left side of mutating operator isn't mutable: 'self' is immutable”。

Xcode真正的意思是,默认情况下,Swift不允许您在扩展中修改self。原因是我们可以使用5.plusOne()来调用plusOne(),显然您不能将数字5修改为其他含义。

因此,Swift迫使您使用mutating声明方法,这意味着它将改变其输入。将扩展名更改为此:

代码语言:javascript复制
extension Int {
    mutating func plusOne() {
        self  = 1
    }
}

现在错误消息将消失。一旦将方法声明为mutating,Swift就会知道它会更改值,因此它不会让您将其与常量一起使用。例如:

代码语言:javascript复制
var myInt = 10
myInt.plusOne()

let otherInt = 10
otherInt.plusOne()

第一个整数将被正确修改,但是第二个将失败,因为Swift不允许您修改常量。直接使用数字调用也将报错: "Cannot use mutating member on immutable value: literals are not mutable", 直接使用数字被称为"字面量",报错信息为,字面量不是可变的。

对于开发人员而言,使用扩展为事物添加功能是极为普遍的。在某些方面,扩展与子类相似,那么为什么要使用扩展?

主要原因是可扩展性:扩展适用于所有数据类型,并且当您拥有多个扩展类型时,它们不会冲突。 使用扩展,您可以在十个不同的文件中具有十个不同的功能-它们都可以直接修改同一类型,并且您无需继承任何子类。用于命名扩展文件的常见命名方案是Type Modifier.swift,例如String RandomLetter.swift。

如果您发现自己经常用字符串修剪空格,您可能会厌倦使用这种怪诞的功能:

代码语言:javascript复制
str = str.trimmingCharacters(在:.whitespacesAndNewlines中)

…所以为什么不做这样的扩展:

代码语言:javascript复制
extension String {
    mutating func trim() {
        self = trimmingCharacters(in: .whitespacesAndNewlines)
    }
}

您可以根据需要扩展任意数量,尽管将不同的功能分隔到单个文件中是一个很好的做法。

本文来自Hacking with Swift 给 swift 初学者的入门课程 Swift for Complete Beginners 的 Extensions

0 人点赞