Codable在Swift 4中得到了介绍。我的项目语言版本是Swift 3.3,但我仍然可以在项目中使用Codable。这不是问题,但是怎么可能呢?我只想知道。
答案 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),根据兼容模式将编译器映射到语言版本:
(请注意,现在实现了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编译器一起编译。
如果将Decodable
和Encodable
协议标记为@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编译器。