typealias和泛型接口
typealias 是用来为已经存在的类型重新定义名字的,通过命名,可以使代码变得更加清晰。使用的语法也很简单,使用 typealias 关键字像使用普通的赋值语句一样,可以将某个已经存在的类型赋值为新的名字。比如在计算二维平面上的距离和位置的时候,我们一般使用 Double
来表示距离,用 CGPoint
来表示位置:
func distanceBetweenPoint(point: CGPoint, toPoint: CGPoint) -> Double {
let dx = Double(toPoint.x - point.x)
let dy = Double(toPoint.y - point.y)
return sqrt(dx * dx + dy * dy)
}
let origin: CGPoint = CGPoint(x: 0, y: 0)
let point: CGPoint = CGPoint(x: 1, y: 1)
let distance: Double = distanceBetweenPoint(origin, point)
虽然在数学上和最后的程序运行上都没什么问题,但是阅读和维护的时候总是觉得有哪里不对。因为我们没有将数学抽象和实际问题结合起来,使得在阅读代码时我们还需要在大脑中进行一次额外的转换:CGPoint
代表一个点,而这个点就是我们在定义的坐标系里的位置;Double
是一个数字,它代表两个点之间的距离。
如果我们使用 typealias,就可以将这种转换直接写在代码里,从而减轻阅读和维护的负担:
import UIKit
typealias Location = CGPoint
typealias Distance = Double
func distanceBetweenPoint(location: Location,
toLocation: Location) -> Distance {
let dx = Distance(location.x - toLocation.x)
let dy = Distance(location.y - toLocation.y)
return sqrt(dx * dx + dy * dy)
}
let origin: Location = Location(x: 0, y: 0)
let point: Location = Location(x: 1, y: 1)
let distance: Distance = distanceBetweenPoint(origin, toLocation: point)
同样的代码,在 typealias 的帮助下,读起来就轻松多了。可能单单这个简单例子不会有特别多的体会,但是当你遇到更复杂的实际问题时,你就可以不再关心并去思考自己代码里那些成堆的 Int
或者 String
之类的基本类型到底代表的是什么东西了,这样你应该能省下不少脑细胞。
对于普通类型并没有什么难点,但是在涉及到泛型时,情况就稍微不太一样。首先,typealias 是单一的,也就是说你必须指定将某个特定的类型通过 typealias 赋值为新名字,而不能将整个泛型类型进行重命名。下面这样的命名都是无法通过编译的:
这是错误代码
class Person<T> {}
typealias Worker = Person
typealias Worker = Person<T>
typealias Worker<T> = Person<T>
一旦泛型类型的确定性得到保证后,我们就可以重命名了:
class Person<T> {}
typealias WorkId = String
typealias Worker = Person<WorkId>
另一个值得一提的是 Swift 中是没有泛型接口的,但是使用 typealias,我们可以在接口里定义一个必须实现的别名,这在一定范围内也算一种折衷方案。比如在 GeneratorType
和 SequenceType
这两个接口中,Swift 都用到了这个技巧,来为接口确定一个使用的类似泛型的特性:
protocol GeneratorType {
typealias Element
mutating func next() -> Self.Element?
}
protocol SequenceType {
typealias Generator : GeneratorType
func generate() -> Self.Generator
}
在实现这些接口时,我们不仅需要实现指定的方法,还要实现对应的 typealias,这其实是一种对于接口适用范围的抽象和约束。
typealias和泛型接口的更多相关文章
- Swift开发第九篇——Any和AnyObject&typealias和泛型接口
本篇分为两部分: 一.Swift中的Any和AnyObject 二.Swift中的typealias和泛型接口 一.Swift中的Any和AnyObject 在 Swift 中,AnyObject 可 ...
- swifter技巧(100)
一.swift新元素 Tip1:柯里化 将方法进行柯里化,把接受多个参数的方法变换成接受第一个参数的方法,并且返回接受余下的参数,返回结果的新方法. func addTwoNumbers(a: Int ...
- 让我们用心感受泛型接口的协变和抗变out和in
关键字out和in相信大家都不陌生,系统定义的很多泛型类型大家F12都或多或少看见了.但是实际中又很少会用到,以前在红皮书里看到,两三页就介绍完了.有的概念感觉直接搬出来的,只是说这样写会怎样,并没有 ...
- Java泛型学习笔记 - (五)泛型接口
所谓泛型接口, 类似于泛型类, 就是将泛型定义在接口上, 其格式如下: public interface 接口名<类型参数>如: interface Inter<T> { pu ...
- java 泛型 -- 泛型类,泛型接口,泛型方法
泛型T泛型的许多最佳例子都来自集合框架,因为泛型让您在保存在集合中的元素上指定类型约束.在定义泛型类或声明泛型类的变量时,使用尖括号来指定形式类型参数.形式类型参数与实际类型参数之间的关系类似于形式方 ...
- java 泛型接口示例
/* * 泛型接口 */ interface Tool<t> { public void show(T t); //泛型方法 public <e> void print(E e ...
- java 16 -7 泛型方法和泛型接口(泛型类相似)
写一个ObjectTool类 泛型方法:把泛型定义在方法上 格式 public <泛型类型> 返回类型 方法名(泛型类型) 这样的好处是: 这个泛型方法可以接收任意类型的数据 public ...
- 三 mybatis typeAlias(别名)使用和resultMap使用
1.MyBatis提供的typeAlias
- C#泛型接口
为泛型集合类或表示集合中项的泛型类定义接口通常很有用.对于泛型类,使用泛型接口十分可取,例如使用 IComparable<T> 而不使用 IComparable,这样可以避免值类型的装箱和 ...
随机推荐
- 一张图说明CDN网络的原理
原文: http://blog.csdn.net/coolmeme/article/details/9468743 1.用户向浏览器输入www.web.com这个域名,浏览器第一次发现本地没有dns缓 ...
- SQL Server Database 维护计划创建完整的备份策略
SQL Server的维护计划Maintenance Plan是一个非常实用的维护工具,可以完成大多数的数据库维护任务,通过对这些功能的封装,可以省去很多的代码编写时间.网络上完整介绍的不是很多,特此 ...
- 51nod1228 序列求和(自然数幂和)
与UVA766 Sum of powers类似,见http://www.cnblogs.com/IMGavin/p/5948824.html 由于结果对MOD取模,使用逆元 #include<c ...
- 带callback的future实现
jdk暂时不支持,所以只有自己实现带callback的future. 完成后callback的 final TaskPromise promise = new DefaultTaskPromise() ...
- Win10 UWP vs add github
vs github 插件 教程 官方教程 点击查看存储库,跳转到 DemoHttp for github
- 关联挖掘和Aprioir算法
Apriori算法 优点:易编码实现 缺点:在大数据集上可能较慢 适用数据类型:数值型或者标称型 算法过程: 关联分析是一种在大规模数据集中寻找有意思的关系的任务,这里的有意思的关系有两种:频繁项集( ...
- CookieManager
CookieSyncManager.createInstance(context); CookieManager cookieManager = CookieManager.getInstance() ...
- java实例化对象的方式
一.Java中创建(实例化)对象的五种方式 1.用new语句直接创建对象,这是最常见的创建对象的方法. 2.通过工厂方法返回对象,如:String str = String.valueOf(23); ...
- POJ 2251 题解
Dungeon Master Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 27520 Accepted: 10776 ...
- tornado 学习笔记6 Application 源码分析
Application 是Tornado重要的模块之一,主要是配置访问路由表及其他应用参数的设置. 源代码位于虚拟运行环境文件夹下(我的是env),具体位置为env > lib>sit-p ...