Fundamentals 6 min read

Swift 4.1 Conditional Conformance Explained

Swift 4.1 introduced Conditional Conformance, allowing extensions of generic types like Array to conform to protocols like Equatable when their elements are Equatable, enhancing both static and runtime type checking.

Liulishuo Tech Team
Liulishuo Tech Team
Liulishuo Tech Team
Swift 4.1 Conditional Conformance Explained

随着 Xcode 9.3 的正式版发布,Swift 4.1 和 iOS 11.3 也一同正式亮相,Swift 4.1 加了什么呢?语言方面主要是围绕 泛型 做了加强。首先我们来了解一下 Conditional Conformance。

我们知道 Array 是个泛型 struct ,它有个类型参数是 Element 。现在我们想让 Array 实现 Equatable 协议,当然有个条件,需要实际的 Element 类型本身实现 Equatable 。这是个很自然的条件,因为如果 Element 不支持相等比较的话,我们也没有办法写出 Array 的相等比较扩展。

上面这一段话其实就是在描述 Conditional Conformance ,于是我们很自然地会这么写:

extension Array: Equatable where Element: Equatable {

很遗憾,这段代码在 Swift 4.0 当中是编译不过的,第一行报错

Extension of type 'Array' with constraints cannot have an inheritance

这里 :Equatable 冒犯了 Swift 4.0 的编译器,有 where 子句的扩展就不能有继承子句。

在 Swift 4.1 中,这个特性得以被支持。大家可以练习一下实现这个方法代替 return true 。而事实上,新的标准库已经加入了这个扩展。另外,这里有个旧知识的复习, Equatable 还有个 != 方法为什么不需要实现呢?答案是默认实现。

我们来看一下这个扩展的用途:多维数组的比较,这里a1和a2都是 Array<Array<Int>> ,我们看到由于 Int 是 Equatable ,所以 Array<Int> 也是 Equatable ,因此 Array<Array<Int>> 是Equatable,可以直接比较。

let a1 = [[123], [456,789]]

关于 Conditional Conformance 还有一个非常重要的特性,就是它对于运行时检查 conformance 的支持。来看下面的代码:

protocol P {

我们看到了两个版本,前者是编译器确定了这个扩展的有效性;后者是 runtime 的时候做检查,它体现了 Conditional Conformance 对动态检查的支持。

如何来直观感受运行时检查 Conditional Conformance 这个特性的作用呢?我们可以想象是自己是被传入的参数:我是个普通的 Array,只不过我的元素类型实现了 P。结果发现我实现了个新的 protocol P,并且拥有了新方法 doSomething 。哪怕我是被作为 Any 类型传入的,动态也能判断上述事实。我只是个 Array ,元素类型实现了 P 而已。 Conditional Conformance 的扩展使这一切成为可能。

最后再回顾一个知识点,为什么我们最后需要新写个 protocol P 来举例,不直接用前面的 Equatable 呢?

用另一个问题可以回答:在Swift中,可不可以写 as? Equatable ,或者 var e : Equatable = 10 呢?其实是不能的,因为 Equatable 这样的 protocol 只能作为泛型的类型约束,而不能作为可以直接 hold 值的类型,原因是它有 associated type 或者 Self ;也没有 Equatable<Int> 的写法,Equatable 不是泛型类型,只是泛型约束。

小结

介绍了 Conditional Conformance 的语法和语义

以 Array 为例介绍了 Conditional Conformance 用途以及标准库的引入

Conditional Conformance 支持动态判断

ProgrammingiOS DevelopmentSwiftLanguage FeaturesGeneric TypesConditional ConformanceSwift 4.1
Liulishuo Tech Team
Written by

Liulishuo Tech Team

Help everyone become a global citizen!

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.