博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Swift - 关键字(typealias、associatedtype)
阅读量:7245 次
发布时间:2019-06-29

本文共 2327 字,大约阅读时间需要 7 分钟。

Typealias

typealias 是用来为已经存在的类型重新定义名字的,通过命名,可以使代码变得更加清晰。使用的语法也很简单,使用typealias 关键字像使用普通的赋值语句一样,可以将某个已经存在的类型赋值为新的名字。比如在计算二维平面上的距离和位置的时候,我们一般使用Double来表示距离,用CGPoint来表示位置:

 

[javascript]   
  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.   
  7. let origin = CGPoint(x: 3, y: 0)  
  8. let point = CGPoint(x: 4, y: 0)  
  9.   
  10. let d = distance(origin, point)  
虽然在数学上和最后的程序运行上都没什么问题,但是阅读和维护的时候总是觉得有哪里不对。 因为我们没有将数学抽象和实际问题结合起来,使得在阅读代码时我们还需要在大脑中进行一次额外的转换:CGPoint代表一个点,而这个点就是我们在定义的坐标系里的位置; Double是一个 数字,它代表两个点之间的距离。
 
如果我们使用 typealias,就可以将这种转换直接写在代码里,从而减轻阅读和维护的负担:

 

[javascript]   
  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.   
  7. let origin = Location(x: 3, y: 0)  
  8. let point = Location(x: 4, y: 0)  
  9.   
  10. let d = distance(origin, point)  
同样的代码,在 typealias 的帮助下,读起来就轻松多了。可能单单这个简单例子不会有特别多的 体会,但是当你遇到更复杂的实际问题时,你就可以不再关心并去思考自己代码里那些成堆的Int或者String之类的基本类型到底代表的是什么东西了,这样你应该能省下不少脑细胞。注意:开发过程中,当使用的比包的使用,会经常使用typealias

 

[javascript]   
  1. typealias Success = (_ data: String) -> Void  
  2. typealias Failure = (_ error: String) -> Void  
  3.   
  4. func request(_ url: String, success: Success, failure: Failure) {  
  5.     // do request here ....  
  6. }  

typealias与泛型

typealias 是单一的,也就是说你必须指定将某个特定的类型通过typealias赋值为新名字,而不能将整个泛型类型进行重命名。下面这样的命名都是无法通过编译的:

 

[javascript]   
  1. class Person<T> {}  
  2. typealias Woker = Person  
  3. typealias Worker = Person<T>  
不过如果我们在别名中也引入泛型,是可以进行对应的
 
[javascript]   
  1. class Person<T> {}  
  2. typealias Woker = Person  
  3. typealias Worker<T> = Person<T>  
当泛型类型的确定性得到保证后,显然别名也是可以使用的:

 

[javascript]   
  1. class Person<T> {}  
  2. typealias WorkId = String  
  3. typealias Worker = Person<WorkId>  
另一个使用场景是某个类型同时实现多个协议的组合时。我们可以使用&符号连接几个协议,然后给它们一个新的更符合上下文的名字,来增强代码可读性:

 

[javascript]   
  1. protocol Cat {}  
  2. protocol Dog {}  
  3. typealias Pat = Cat & Dog  

associatedtype关联类型

 
定义一个协议时,有的时候声明一个或多个关联类型作为协议定义的一部分将会非常有用。关联类型为协议中的某个类型提供了一个占位名(或者说别名),其代表的实际类型在协议被采纳时才会被指定。你可以通过 associatedtype 关键字来指定关联类型。比如使用协议声明更新cell的方法:

 

[javascript]   
  1. //模型  
  2. struct Model {  
  3.     let age: Int  
  4. }  
  5.   
  6. //协议,使用关联类型  
  7. protocol TableViewCell {  
  8.     associatedtype T  
  9.     func updateCell(_ data: T)  
  10. }  
  11.   
  12. //遵守TableViewCell  
  13. class MyTableViewCell: UITableViewCell, TableViewCell {  
  14.     typealias T = Model  
  15.     func updateCell(_ data: Model) {  
  16.         // do something ...  
  17.     }  
  18. }  

 

 

转载地址:http://coybm.baihongyu.com/

你可能感兴趣的文章
Cassandra查询语言CQL的基本使用
查看>>
echo输出到stderr
查看>>
Leetcode: Search a 2D Matrix II
查看>>
Unicode与 utf8的互相转换
查看>>
Android开发周报:Flyme OS开源、经典开源项目解析
查看>>
uva 568(数学)
查看>>
【Hibernate】Hibernate系列4之配置文件详解
查看>>
centos7+redis+php环境配置
查看>>
割点、桥模板以及点双连通、边双连通
查看>>
Yii数据库操作增删改查-[增加\查询\更新\删除 AR模式]
查看>>
vs发布的程序不依赖运行时库msvcp100.dll
查看>>
jsp简单实现统计在线人数
查看>>
df、du、fdisk:Linux磁盘管理
查看>>
C#时间戳转换[转发]
查看>>
MySQL · 答疑解惑 · MySQL 锁问题最佳实践
查看>>
SDK的制作详解
查看>>
$.ajax()方法详解
查看>>
ssh登录很慢,登录上去后速度正常问题的解决方法
查看>>
socket实例1
查看>>
python 类
查看>>