此页面介绍了 Swift 的协议一致性检查系统,该系统可验证给定类型是否正确地符合协议。一致性检查器会分析值和类型见证,匹配函数签名,并执行关联类型推断,以确保类型满足所有协议要求。
有关基于约束的类型检查系统的信息,请参阅基于约束的类型检查。有关 Swift 并发类型检查的详细信息,请参阅并发类型检查。
协议一致性检查是 Swift 类型系统的一个关键组成部分,可确保面向协议编程的静态类型安全。当一个类型声明符合某个协议时,编译器会验证:
来源:lib/Sema/TypeCheckProtocol.cpp1-16 lib/Sema/TypeCheckProtocol.h98-108
协议一致性检查系统包含几个相互关联的组件。
来源:lib/Sema/TypeCheckProtocol.h30-127 lib/Sema/TypeCheckProtocol.h109-175
WitnessChecker:基类,提供将见证匹配到要求的功能。
ConformanceChecker:管理整体一致性检查过程,包括查找和验证见证。
RequirementMatch:表示将见证匹配到要求的結果,包括成功或具体的失败原因。
AssociatedTypeInference:处理关联类型见证的推断,当它们没有被明确提供时。
见证匹配是确定符合类型中的声明是否满足协议要求的过程。这主要在 matchWitness 函数中实现。
在详细类型检查之前,系统会执行结构匹配以确保基本兼容性。
来源:lib/Sema/TypeCheckProtocol.cpp512-691
结构匹配后,类型检查确保参数和返回类型兼容。
来源:lib/Sema/TypeCheckProtocol.cpp702-936
当协议定义关联类型时,符合类型的类型必须显式声明类型见证,或者由编译器推断。
来源:lib/Sema/AssociatedTypeInference.cpp442-637 lib/Sema/AssociatedTypeInference.cpp1065-1211
关联类型推断系统使用多种策略来确定类型见证。
当多种策略建议不同见证时,系统会尝试找到最佳解决方案或报告歧义。
来源:lib/Sema/AssociatedTypeInference.cpp1064-1107 lib/Sema/AssociatedTypeInference.cpp244-421
一旦确定了潜在的类型见证(通过显式声明或推断),就必须根据关联类型的要求对其进行验证。
来源:lib/Sema/AssociatedTypeInference.cpp147-217
将要求与见证匹配的结果封装在 RequirementMatch 对象中,该对象描述了匹配是否成功以及原因。
| 匹配类型 | 描述 |
|---|---|
精确 | 见证与要求完全匹配。 |
类型冲突 | 声明类型不匹配(例如,方法与属性)。 |
类型冲突 | 要求和见证之间的类型不匹配。 |
变异冲突 | 变异/非变异不匹配。 |
Throws 冲突 | Throws 行为不匹配。 |
Async 冲突 | Async 行为不匹配。 |
Rethrows 冲突 | Rethrows 行为不匹配。 |
缺少要求 | 见证不满足要求。 |
见证无效 | 见证声明无效。 |
可设置冲突 | 属性可设置性不匹配。 |
来源:lib/Sema/TypeCheckProtocol.cpp175-199 lib/Sema/TypeCheckProtocol.cpp514-681
协议一致性检查包含对各种边缘情况的特殊处理。
在符合 Objective-C 协议或使用 Objective-C 方法作为见证时,系统会:
来源:lib/Sema/TypeCheckProtocol.cpp204-247 lib/Sema/TypeCheckProtocol.cpp100-202
对于带有 @differentiable 属性的协议,一致性检查器会:
来源:lib/Sema/TypeCheckProtocol.cpp310-489
协议一致性检查可验证要求和见证之间的适当 Actor 隔离。
来源:lib/Sema/TypeCheckProtocol.cpp834-847 lib/Sema/TypeCheckProtocol.cpp875-884
协议一致性检查的总体工作流程遵循以下步骤:
来源:lib/Sema/TypeCheckProtocol.h145-157 lib/Sema/TypeCheckProtocol.cpp1015-1085 lib/Sema/AssociatedTypeInference.cpp1209-1211
Swift 标准库广泛使用了协议一致性和关联类型推断。 AsyncSequence 协议提供了一个很好的例子,说明了关联类型推断如何与相关协议协同工作。
当一个类型符合 AsyncSequence 时,一致性检查系统会:
makeAsyncIterator() 的见证。Iterator 关联类型的见证。Element 必须与迭代器的元素类型相同。Failure 类型,要么使用显式见证,要么从迭代器的失败类型推断。测试文件 async_sequence_conformance.swift 演示了此推断机制。
来源: test/ModuleInterface/async_sequence_conformance.swift7-69 lib/Sema/AssociatedTypeInference.cpp420-440
协议一致性检查可能遇到几个常见问题。
当类型未为协议要求提供实现时,系统会报告一个缺失见证的错误。
当多个潜在的类型见证可以满足关联类型的要求时,系统会报告一个歧义。
当类型推断为同一关联类型产生冲突的类型见证时,系统必须解决该冲突或报告一个错误。
当建议的类型见证未能满足关联类型的约束(协议一致性、超类要求等)时,系统会报告一个关于哪个约束未被满足的特定错误。
来源: lib/Sema/AssociatedTypeInference.cpp584-602 lib/Sema/AssociatedTypeInference.cpp602-635
协议一致性检查是一个复杂的系统,可确保 Swift 协议导向设计中的类型安全。通过结合显式见证验证和强大的类型推断能力,它在灵活性和编译时安全性保证之间取得了平衡。该系统与 Swift 类型检查器的其他部分紧密协作,以验证声明的一致性是否满足所有协议要求,并在不满足时生成全面的诊断信息。