Typealias

typealias 是用来为已经存在的类型重新定义名字的,通过命名,可以使代码变得更加清晰。使用的语法也很简单,使用typealias 关键字像使用普通的赋值语句一样,可以将某个已经存在的类型赋值为新的名字。比如在计算二维平面上的距离和位置的时候,我们一般使用Double来表示距离,用CGPoint来表示位置:
  1. func distance(_ point: CGPoint, _ anotherPoint: CGPoint) -> Double {
  2. let dx = Double(anotherPoint.x - point.x)
  3. let dy = Double(anotherPoint.y - point.y)
  4. return sqrt(dx * dx + dy * dy)
  5. }
  6. let origin = CGPoint(x: 3, y: 0)
  7. let point = CGPoint(x: 4, y: 0)
  8. let d = distance(origin, point)
虽然在数学上和最后的程序运行上都没什么问题,但是阅读和维护的时候总是觉得有哪里不对。 因为我们没有将数学抽象和实际问题结合起来,使得在阅读代码时我们还需要在大脑中进行一次额外的转换:CGPoint代表一个点,而这个点就是我们在定义的坐标系里的位置; Double是一个 数字,它代表两个点之间的距离。
 
如果我们使用 typealias,就可以将这种转换直接写在代码里,从而减轻阅读和维护的负担:
  1. func distance(_ point: CGPoint, _ anotherPoint: CGPoint) -> Double {
  2. let dx = Distance(anotherPoint.x - point.x)
  3. let dy = Distance(anotherPoint.y - point.y)
  4. return sqrt(dx * dx + dy * dy)
  5. }
  6. let origin = Location(x: 3, y: 0)
  7. let point = Location(x: 4, y: 0)
  8. let d = distance(origin, point)
同样的代码,在 typealias 的帮助下,读起来就轻松多了。可能单单这个简单例子不会有特别多的 体会,但是当你遇到更复杂的实际问题时,你就可以不再关心并去思考自己代码里那些成堆的Int或者String之类的基本类型到底代表的是什么东西了,这样你应该能省下不少脑细胞。注意:开发过程中,当使用的比包的使用,会经常使用typealias
  1. typealias Success = (_ data: String) -> Void
  2. typealias Failure = (_ error: String) -> Void
  3. func request(_ url: String, success: Success, failure: Failure) {
  4. // do request here ....
  5. }

typealias与泛型

typealias 是单一的,也就是说你必须指定将某个特定的类型通过typealias赋值为新名字,而不能将整个泛型类型进行重命名。下面这样的命名都是无法通过编译的:
  1. class Person<T> {}
  2. typealias Woker = Person
  3. typealias Worker = Person<T>
不过如果我们在别名中也引入泛型,是可以进行对应的
 
  1. class Person<T> {}
  2. typealias Woker = Person
  3. typealias Worker<T> = Person<T>
当泛型类型的确定性得到保证后,显然别名也是可以使用的:
  1. class Person<T> {}
  2. typealias WorkId = String
  3. typealias Worker = Person<WorkId>
另一个使用场景是某个类型同时实现多个协议的组合时。我们可以使用&符号连接几个协议,然后给它们一个新的更符合上下文的名字,来增强代码可读性:
  1. protocol Cat {}
  2. protocol Dog {}
  3. typealias Pat = Cat & Dog

associatedtype关联类型

 
定义一个协议时,有的时候声明一个或多个关联类型作为协议定义的一部分将会非常有用。关联类型为协议中的某个类型提供了一个占位名(或者说别名),其代表的实际类型在协议被采纳时才会被指定。你可以通过 associatedtype 关键字来指定关联类型。比如使用协议声明更新cell的方法:
  1. //模型
  2. struct Model {
  3. let age: Int
  4. }
  5. //协议,使用关联类型
  6. protocol TableViewCell {
  7. associatedtype T
  8. func updateCell(_ data: T)
  9. }
  10. //遵守TableViewCell
  11. class MyTableViewCell: UITableViewCell, TableViewCell {
  12. typealias T = Model
  13. func updateCell(_ data: Model) {
  14. // do something ...
  15. }
  16. }
 

最新文章

  1. flexbox布局神器
  2. mysql时间日期相加相减实现
  3. Oracle笔记 十二、PL/SQL 面向对象oop编程
  4. myplan
  5. 放弃SCOPE_Identity,使用OUTPUT代替
  6. activemq 一个不错的ppt
  7. YZOI Easy Round 2_回文串 string
  8. mvcc摘抄
  9. SpringBoot 配置文件 application.properties(二)
  10. UISegmentControl 、UIStepper
  11. linux-mint下搭建android,angularjs,rails,html5开发环境 - qijie29896的个人空间 - 开源中国社区
  12. SVN与eclipse整合与使用、SVN与Apache整合
  13. ThinkPHP部署在lnmp环境中碰到的问题
  14. MySQL数据库(增删改查语句)
  15. 小技巧:改变 VS Code 工作区页面背景
  16. SpringBoot 使用Druid连接池
  17. java中int和Integer对比的一些坑
  18. Xcode提交图片出错:Commit failed not under version control (1)
  19. 安装支持eigen线性迭代的ceres_solver
  20. Windows下 搭建redis集群

热门文章

  1. 51nod1081 子段求和
  2. MongoDB简介、特点、原理、使用场景、应用案例
  3. 【codeforces 350C】Bombs
  4. 字体大小之px、em、rem、pt,字号详解
  5. Spring Cloud-Ribbon实现客户端的服务均衡(三)
  6. nodejs-n-nvm版本管理工具
  7. 【转载】linux中shell命令test用法和举例
  8. IT人才异军突起 有招网引领业界精英
  9. KeyEvent 键码值
  10. jquery 页眉单行信息滚动显示