为什么我可以将Codable与Swift 3.3的项目语言版本一起使用?

时间:2018-07-11 09:18:11

标签: swift codable

Codable在Swift 4中得到了介绍。我的项目语言版本是Swift 3.3,但我仍然可以在项目中使用Codable。这不是问题,但是怎么可能呢?我只想知道。

2 个答案:

答案 0 :(得分:4)

Swift编译器版本和“ Swift语言版本”构建设置(与
-swift-version命令行标志相对应)是两件事。前者是您使用的编译器和标准库的 actual 版本,而后者只是一个标志,告诉编译器尝试模仿以前的Swift版本的行为。这样可以提供更流畅的迁移体验-您可以更新到最新的Swift编译器,而不必立即更新代码库来适应语言的最新更改。

在您的情况下,听起来好像您使用的是Swift 4.1编译器,并且“ Swift语言版本”设置为Swift 3.3。这就是所谓的“ Swift 3兼容模式”。请注意,Swift 3.3版本是伪版本–仅存在于代表以Swift 3兼容模式运行的Swift 4.1编译器。

这是一个方便的表(信息来自SE-0212),根据兼容模式将编译器映射到语言版本:

enter image description here

(请注意,现在实现了SE-0212,对于兼容模式,该版本不再适用于Swift 5及更高版本)

因此,这意味着您正在使用Swift 4.1标准库(包括新的Codable协议)并使用Swift 4.1编译器进行编译(包括用于Codable合成的必要编译器魔术) 。这就是为什么您仍然可以利用新的Codable协议的原因。

但是,通过在Swift 3兼容模式下运行,您正在指示编译器模仿Swift 3编译器的行为。例如,这将导致它允许您访问标记为@available(swift, obsoleted: 4)的声明,阻止您访问标记为@available(swift, introduced: 4)的声明,忽略#if swift(>=4)条件编译块中的代码,否则执行它最好保持与Swift 3的源兼容性。

后者并非总是能完美实现,例如,它使用Swift 3.1编译器进行编译:

protocol P {}
typealias X = protocol<P, AnyObject>
class C : X {}

,但不能与以Swift 3兼容模式(SR-8153)运行的Swift 4.1编译器一起编译。

如果将DecodableEncodable协议标记为@available(swift, introduced: 4),那么您实际上将无法在Swift 3兼容模式下访问它们。但是没有真正的理由将它们标记为此类,因为没有真正的理由阻止人们在Swift 3模式下利用它们,因为Swift 4编译器完全支持它们。

但是,由于Swift 3兼容模式仅是一种–源兼容性的临时模式,因此您无法在以后的编译器版本中永久使用它。 will no longer be an option in the Swift 5 compiler(但是您将具有Swift 4的兼容模式)。因此,您需要确保在某个时候将代码库更新到Swift 4,以便能够顺利迁移到Swift 5编译器。

最后,值得注意的是,新的compiler指令(可以在条件编译块中使用)is being introduced in Swift 4.2。与#if swift(...)检查-swift-version提供的语言版本不同,#if compiler(...)将检查编译器的实际版本,而忽略了它可能在其中运行的任何兼容模式。

答案 1 :(得分:1)

我认为您可能正在使用最新的Swift编译器。