在本章中,你将学会Generics
泛型的使用方法。
前言
和Apple
官网或者网上分享的教程类文章不同,我将以实际开发角度讲述Swift
语言的一些概念和用法,方便大家更好地学习和掌握Swift
语言。
这同时也是对自己学习Swift
语言过程的知识整理。
如有错误,以你为准。
项目创建
我们新建一个PlayGround
项目,命名为SwiftGenerics
。
泛型定义
泛型,是一种不确定的数据类型。
泛型允许我们在编写代码时使用一些以后才指定的类型,并能在实例化时作为参数指明这些类型。
简单来说,泛型就是一个“占位符
”,用来代替当前不确定的类型。
泛型函数
泛型函数使用到了一个“_
”占位类型来代替参数值,从而提高代码复用率,减少代码量。示例:
func gotoAppStore(appId: String) { let urlPrex = "itms-apps" let appUrl = urlPrex + "://itunes.apple.com/app/id" + appId let appNsUrl = NSURL(string: appUrl) UIApplication.shared.open(appNsUrl! as URL, options: [:], completionHandler: nil) } gotoAppStore(appId: "App的ID")
上述代码是我们学习过的通过传入一个String
类型的appId
参数,然后跳转到AppStore
的方法。
调用的时候,我们会指定传入的参数,这里使用的参数是appId
。
但如果我们使用泛型函数,就可以不指定参数,泛型可以将类型参数化。示例:
func gotoAppStore(_ appId: String) { let urlPrex = "itms-apps" let appUrl = urlPrex + "://itunes.apple.com/app/id" + appId let appNsUrl = NSURL(string: appUrl) UIApplication.shared.open(appNsUrl! as URL, options: [:], completionHandler: nil) } gotoAppStore("App的ID")
使用泛型函数,我们就不需要指定参数,直接调用方法,达到减少代码量的效果,这也算是Apple
官方极度追求代码优雅的结果。
Swift
标准库是通过泛型代码构建出来的,像我们之前学习过的数组、字典其实也都是泛型集合。
泛型类型
除了可以使用泛型函数减少代码量外,我们还可以自定义泛型类型,如果我们提前不知道需要接受到的数据类型,我们就可以先定义好一个泛型类型,然后确定类型后直接调用方法。示例:
struct Example<ArrayElement> { var items = [ArrayElement]() mutating func push(_ item: ArrayElement) { items.append(item) } }
上述代码中,我们定义了一个自定义类型的结构体Example
,在Example
结构体中,我们声明了一个items
数组,它也是自定义类型的。
然后写了一个方法,通过泛型函数的方法传入参数,将传入的参数添加到自定义类型的items
数组中。
我们可以发现,我们在声明数组时是没有指定这个数组是什么类型的,Example
结构体传入也是,它就是泛型类型。
这样在我们在后面确定好传入的参数类型后,我们就不需要重新修改数组的类型。示例:
var exampleStrings = Example<String>() exampleStrings.push("文如秋雨")
上述代码中,我们声明了一个exampleStrings
变量,它给Example
结构体定义了String
类型,后面我们就可以直接调用push
传入相应类型的参数即可。
关联类型
在我们定义协议时,我们对于协议中的属性也可以使用到泛型的方法,这里提及一个关联属性的概念,也就是我们在协议中可以先不定义属性的类型,而在使用的时候再确定属性的类型。示例:
protocol Person { associatedtype FullName mutating func push(_ item: FullName) }
上述代码中,我们定义了一个Person
协议,然后使用associatedtype
关键字声明了一个还不确定类型的参数FullName
。
然后依旧写了一个接收泛型函数的方法push
,我们再定义一个class
来遵循这个协议。示例:
class People: Person { typealias FullName = String func push(_ item: String) { print("输入的FullName是String") } } var exampleStrings2 = People() exampleStrings2.push("文如秋雨")
上述代码中,我们定义了一个类People
,遵循Person
协议,然后调用typealias
关键字,给FullName
参数设置了一个关联类型String
。
然后在方法中传入参数,打印输出文字。
我们可以通过上面的方法知道,使用关联类型时,我们就不需要在提前设置参数的类型,在我们实际业务中使用到了我们再定义,也就不用老是修改代码,从而提高代码复用率,减少代码量。
以上就是本章的全部内容。
快来动手试试吧!
如果本专栏对你有帮助,不妨点赞、评论、关注~