快速,更优雅的代码:Typealias
您是否在使用长签名功能时遇到麻烦? 您认为重命名某些类型是个好主意吗? 好吧……只是看看 typealias 。
什么是Typealias?
我第一次发现有一种叫做“别名”的东西,对我来说有点奇怪,即使知道它的用途后,在我看来,使用它也没有“好”的意义。 到目前为止,我是它的粉丝!
在开始使用Swift typealias之前,我想指出的是,别名并不是 Swift编程语言的专有术语,实际上它是一个计算术语,您可以在许多其他古老和现代的语言中找到“别名”的逻辑(例如作为Swift)编程语言…
Typealias是现有类型的命名别名,这意味着通过使用它,您将能够命名类型,以使程序更方便。 请记住,typealias 不是新类型,它只是现有类型的名称,您可以将其视为类型的替代名称(它可能是“快捷方式”,您将很快阅读)。
如何实现typealias?
简单来说,您可以将typealias实现为:
typealias yourCustomName =现有类型
而这一切!
让我们开始做一些非常简单的代码:
实施:
typealias Strings = [String]
可让您声明字符串数组( [String]
)类型的变量(例如instance),如下所示:
var strs: Strings?
现在strs
将是[String]
类型的变量。
非常有趣! 老实说,对我来说我不这么认为。 如果您想到的是“到目前为止,它是没有用的”,我会同意agree。
毫无疑问,为这种情况创建类型别名在某些情况下将其声明为var strs: [String]?
并不是那么有用var strs: [String]?
读起来会更好。。。让它平静下来,让我们尝试另一种方法:将字符串字典的类型别名声明为键,将整数声明为值:
typealias CustomDict =字典
在声明字典的泛型参数的具体类型( )时,应该节省一些“精力”,就像“双向2合1保存”! 但是,仍然不是使用typealias的充分理由,对吗? 这导致:
为什么要使用typealias?
实际上,通常在使用非平凡的应用程序时,它应该具有自己的管理器来处理指定功能的任务,例如通过网络连接发送和接收数据,获取设备照片(访问系统资源),从磁盘写入数据或从磁盘读取数据等等。因此,实现这些管理器可能需要为其方法使用“相当长”的签名。 让我们更进一步,为更多“真实世界”案例编写一些代码:
例:
为了使其更简单,我将重点介绍方法的签名,而不管它们的实际内部实现是什么(管理者目的)。
考虑我们有包含foo
MyManager
和 bar
方法如下:
class MyManager {
//...
func foo(success: (_ data: Data, _ message: String, _ status: Int, _ isEnabled: Bool) -> (), failure: (_ error: Error, _ message: String, _ workaround: AnyObject) -> ()) {
if isSuccess {
success(..., ..., ..., ...)
} else {
failure(..., ..., ...)
}
}
func bar(success: (_ data: Data, _ message: String, _ status: Int, _ isEnabled: Bool) -> (), failure: (_ error: Error, _ message: String, _ workaround: AnyObject) -> ()) {
if isSuccess {
success(..., ..., ..., ...)
} else {
failure(..., ..., ...)
}
}
// ...
}
到目前为止,还不错,但是请稍等…这些方法签名看起来确实很乏味! 它们都采用success
和failure
参数,我敢打赌,您注意到这两种方法都相同:
success: (_ data: Data, _ message: String, _ status: Int, _ isEnabled: Bool) -> ()
和
failure: (_ error: Error, _ message: String, _ workaround: AnyObject) -> ()
顺便提一句,在您的实际应用中,您可能需要将这些闭包声明为转义闭包…
最终可能会导致阅读混乱的签名……
根据我们的情况,当涉及复合类型时 ,您肯定会注意到声明类型别名的好处。
Typealias在这里为您节省! 所以是的,您可以让这些闭包签名成为类型别名:
typealias Success = (_ data: Data, _ message: String, _ status: Int, _ isEnabled: Bool) -> ()
typealias Failure = (_ error: Error, _ message: String, _ workaround: AnyObject) -> ()
typealias Success = (_ data: Data, _ message: String, _ status: Int, _ isEnabled: Bool) -> ()
typealias Failure = (_ error: Error, _ message: String, _ workaround: AnyObject) -> ()
从而:
class MyManager {
//...
func foo(success: Success, failure: Failure) {
if isSuccess {
success(..., ..., ..., ...)
} else {
failure(..., ..., ...)
}
}
func bar(success: Success, failure: Failure) {
if isSuccess {
success(..., ..., ..., ...)
} else {
failure(..., ..., ...)
}
}
// ...
}
好多了! 在这一点上,它应该更具表现力和可读性。
同样从“可重用性”的角度来看,对于实现类似的功能,使用类型别名而不是保留参数的“复制粘贴”会容易得多。 编辑类型别名的声明将反映在所有管理器方法签名上。
包起来:
Typealiases很有用,即使Swift本身也使用它们,例如,Codable是Decodable和Encodable协议的类型别名。 但是,请记住,您不应过度使用它们,有时不必声明这样的类型别名( typealias Strings = [String]
😄),只需在您认为有用的情况下进行操作即可。
参考:
- Swift编程语言(语言参考-声明):类型Alias声明。
作者✍️
欣赏您的反馈👏敬请关注更多“快速,优雅的代码”主题。
谢谢阅读!