TinyExperience:何时使用内联函数

此文章同时提供中文版本: TinyExperience:内联函数的使用场景

我相信所有使用Swift的人都知道Swift中的功能。 但是内联函数对于大多数开发人员而言可能并不常见。 本文旨在介绍我在日常开发中使用内联函数的方式。

什么是内联函数

我们通常在类,结构,枚举等级别使用函数:

 类示例{ 
func method1(){}
}

内联函数是另一个函数内部的函数,如下所示:

 类示例{ 
func method1(){
func inlineMethod1(){}
}
}

实际上,换句话说,内联函数只是函数的正常用法。 Objective-C不支持嵌套功能,Swift可以修复该功能,甚至不支持多层嵌套。 但是我们要注意的一件事是,内联函数属于本地声明,因此在使用它之前需要对其进行定义。

常用用法

由于我们不需要在Objective-C中使用它,为什么我们会在Swift中使用它呢? 例如,我们经常这样编写视图的初始化代码:

loadView包含许多不同的初始化代码。 编写时可能很清楚,但是稍后查看时会非常混乱。 当然,写评论也是一个清楚的好方法,但是我们写评论的方式也不尽相同。 而且注释与内容没有直接关联,因此,在很多情况下注释无法跟上代码的进度。 更好的方法是使代码描述自己,就像提取到函数中一样,例如:

这应该是我们最常用的方法。 提取的函数使代码更易于理解和处理。 但是有一个问题:那些暴露的initxxx()方法可以从类内部的任何地方直接调用。 尽管我们知道它们只是初始化代码,只应从loadView调用一次,但是代码没有任何限制,您无法控制团队中的其他开发人员。 此时,我们可以使用内联函数解决此问题:

用内联函数替换三个initxxx()方法可以保留代码的结构,同时避免可能的错误调用,并且由于代码更加紧凑且不会分散在本地,因此有助于后期重构。

减少重复代码

减少重复代码始终是该功能的责任。 但是在过去使用Objective-C(仅适用于类级别的函数)时,我们通常仅将通用的重复代码提取到函数中。 一些部分重用的代码我们只是直接重复它们,因为如果所有本地逻辑提取到函数中,都会使我们的类级函数太混乱。
就像下面的示例一样, label.text具有多个重复设置。 该示例可能非常简单,但是我们仍然需要保持两组字符串之间的一致性。

但是使用内联函数,我们可以更彻底地实现DRY原理,以便完全复用复杂的部分,如下所示:

实际上,我们还可以利用函数的其他功能(例如参数传递)来使代码更结构化:

回调优化

除了优化类级别的某些原始功能外,内联函数还可以用于优化某些回调处理问题。 例如,我们经常需要发出网络请求,就会有多个回调,例如以下示例:

但是,当这样请求参数数量时,整个方法调用将非常长且不清楚。 我们可以使用换行符来处理它,但是这次您必须忍受Xcode怪异的缩进逻辑:

参数足够清晰,但是回调内容的缩进太多, }的缩进位置对我来说是不可接受的。 目前,我们可以使用内联函数来解决此问题,在添加两个内联函数之后,我们可以使代码更加清晰:

实际上,您可以像以前一样将onSuccessonFailure方法提取到类层,但是使用内联函数的优点是这两个方法对其他方法不可用,这等效于限制了这些方法的范围。方法很好。 整个代码的结构将整洁,缩进程度低。

这些简单的示例可能无法反映使用内联函数的需要。 但是想象一下,如果同时存在多个请求,并且您需要对所有回调进行一些通用处理。 如果将函数置于类级别,则它将是仅用于特定方法的方法,但以不好的方式可用于所有其他方法。 但是,如果使用内联函数,则仍然可以保持结构和低干扰,例如以下示例:

实际上,内联函数是为了使我们的函数分散在更合适的位置,而不是全部存储在类和结构的第一层,例如在我们类下的private func ,以便在更精细的层次上进行区分。