Swift关键字之 typealias

typealias

1
2
3
4
5
6
7
8
9
10
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)

typealias用来为已经存在的类型重新定义名字,通过命名可以使代码变得更加清晰。比如上段代码,我们用 Double 表示距离,用 CGPoint 表示位置。

虽然在数学上和最后运行上兵没有问题,但是阅读和维护的时候就会产生障碍。CGPoint 代表一个点,这个点是我们定义的坐标系里的位置; Double 是一个数字,它代表两个点之间的距离

如果使用typealias,代码就会变成如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

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, point)

当遇到复杂的实际问题时,你将不在关心 Int 或者 String这类基本类型代表什么。

typealias 在泛型中的作用

首先,typealias 是单一的,你必须指定将某个特定类型通过 typealias 赋值为新名字,而不能将整个泛型类型重命名。下面的代码是无法通过编译的:

1
2
3
4
5
class Person<T> {}
typealias Worker = Person
typealias Worker = Person<T>
typealias Worker<T> = Person<T>
// 这是错误代码

一旦泛型类型的确定性得到保证后,就可以重命名了:

1
2
3
4
class Person<T> {}

typealias WorkId = String
typealias Worker = Person<WorkId>

typelias 在泛型接口中的使用

swift 中是没有泛型接口的,但是使用 typealias,我们可以在接口里定义一个必须实现的别名。比如 GeneratorType 和 SequenceType 这两个接口中,都用 typealias 来确定一个使用协议的类的唯一性:

1
2
3
4
5
6
7
8
9
10
11
protocol GeneratorType {
typealias Element
mutating func next() -> Element?
}

public protocol SequenceType {

typealias Generator : GeneratorType

typealias SubSequence
}

就是说,在遵守 GeneratorType 和 SequenceType 两个协议的时候,通过在里头声明一个 typealias,这个类型别名 Element 是啥,需要由其实现者去填写

文章作者: Ammar
文章链接: http://lizhaoloveit.cn/2015/07/10/Swift%E5%85%B3%E9%94%AE%E5%AD%97%E4%B9%8B-typealias/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Ammar's Blog
打赏
  • 微信
  • 支付宝

评论