Swift 4已经投入使用了近几个月。 如果您像我一样,可以遵循Swift Evolution来了解所有建议和变更。 即使您愿意,现在也是时候回顾一下此新迭代中所有对语言的添加和更改的好时机。

在WWDC 2017上宣布Xcode 9之前,Swift 4的快照已经发布了几周。在这篇文章中,您将了解Swift 4中引入的所有新功能-从全新的API到语言语法的改进。

首先让我们看看如何在计算机上安装新的编译器。

Xcode设置

有两种运行Swift 4的方法。您可以安装Xcode 9 Beta(如果您拥有有权访问它的开发人员帐户),或者可以将Xcode 8设置为与Swift 4快照一起运行。 在前一种情况下,请从您的开发人员帐户下载页面下载测试版。

如果您更喜欢使用Xcode 8,只需转到Swift.org即可下载最新的Swift 4.0 Development快照。 下载完成后, 双击打开.pkg文件,该文件将安装快照。

立即切换到Xcode并转到Xcode>工具链>管理工具链 。 从那里,选择新安装的Swift 4.0快照。 重新启动Xcode,现在在编译项目或游乐场时将使用Swift 4。 请注意,本教程中介绍的所有代码也可以在GitHub存储库中找到 。

swift4_java

新功能

让我们看一下Swift 4中添加的新功能。一个警告:该语言仍处于beta版本,在正式版本发布之前,我们很可能会看到更多更改和错误修复。 此外,某些最新批准的建议可能此时仍未实施,因此请留意将来的发行说明,以了解将要实施和修复的内容。

编码和解码

JSON解析是Swift社区中讨论最多的主题之一。 很高兴看到有人终于完成了写建议SE-0166和SE-0167的工作,并推动了这个想法,以刷新Foundation框架中的归档和序列化API。 在Swift 4中,不再需要手动解析或编码您的类,结构或枚举。

添加了新的Encodable和Decodable协议,您只需将Codable (这是Decodable & Encodable的别名)添加到类的继承列表中,即可使您的类符合它们。 然后,您可以使用JSONEncoder对类的实例进行编码:

let wwdc = Conference(name: "WWDC", city: "San Jose", date: Date(timeIntervalSince1970: 0))
let jsonEncoder = JSONEncoder()
let jsonEncoded = try jsonEncoder.encode(wwdc)
let jsonString = String(data: jsonEncoded, encoding: .utf8) // {"name":"WWDC","city":"San Jose","date":-978307200}

如您所见,您实例化了一个JSONEncoder对象,以将该结构转换为JSON字符串表示形式。 您可以调整一些设置来获取所需的确切JSON格式。 例如,要设置自定义日期格式,可以通过以下方式指定dateEncodingStrategy :

let jsonEncoder = JSONEncoder()
let dateFormatter = DateFormatter()
dateFormatter.dateStyle = .long
dateFormatter.timeStyle = .long
jsonEncoder.dateEncodingStrategy = JSONEncoder.DateEncodingStrategy.formatted(dateFormatter)
let jsonEncoded = try jsonEncoder.encode(wwdc)
let jsonString = String(data: jsonEncoded, encoding: .utf8) // {"name":"WWDC","city":"San Jose","date":"January 1, 1970 at 1:00:00 AM GMT+1"}

多亏了JSONDecoder类,解码字符串的反向过程非常相似。

let jsonDecoder = JSONDecoder()
let decodedWWDC = try jsonDecoder.decode(Conference.self, from: jsonEncoded) // `decodedWWDC` is already of type Conference!

如您所见,通过将对象的类型传递给decode方法,我们使解码器知道我们希望从JSON数据返回什么对象。 如果一切成功,我们将准备好使用模型对象的实例。

这还不只是新API的全部功能和模块化。 如果您需要将数据存储在plist文件中,则可以使用新的PropertyListEncoder和PropertyListDecoder来代替JSONEncoder 。 您还可以创建自己的自定义编码器和解码器。 您只需要使解码器符合Decoder器,并使Encoder器符合编码Encoder协议即可。

弦乐

作为String Manifesto的一部分, String类型也获得了很大的刷新。 由于提议SE-0163,它现在再次符合Collection协议(在Swift 2中被删除)。 因此,现在您只需枚举字符串即可获取所有字符。

let text: String = "Hello from Tutsplus!"
for character in text.reversed() {
    print(character)
}

Substring是一种新类型,它符合String遵循的同一StringProtocol 。 您可以通过对String下标来创建新的Substring 。 下一行通过省略第一个和最后一个字符来创建Substring 。

let substring = text[text.index(after: text.startIndex)..<text.index(before: text.endIndex)]

多行字符串是一个不错的补充,它可以使处理大段文本更加容易。 如果必须创建跨多行的文本块,则以前必须手动在整个位置插入\n 。 这非常不雅且难以管理。 如下面的示例所示,现在存在一种更好的方式来编写多行字符串:

let welcomeMessage = """
  Hey there,
  
  Welcome to Envato Tuts+.
  We hope you enjoy learning with us!
  """

这种新语法几乎没有规则。 每个字符串都以三引号( """ )开头,然后,如果整个字符串都缩进了,则关闭字符的间距决定了要从字符串中的每一行剥离的间距。缩进2个制表符,每行将删除相同的数量如果字符串中的行没有此间距,则编译器将引发错误。

关键路径

在Swift 3中添加了关键路径,以使其更易于引用对象中的属性。 使用键路径,而不是使用简单的字符串文字来引用对象键,而是让我们强制进行编译时检查,以检查类型是否包含必需的键,从而消除常见的运行时错误类型。

密钥路径是Swift 3的一个不错的补充,但是它们的使用仅限于NSObject并且它们在结构上的使用并不十分理想。 这些是建议SE-0161刷新API的主要动机。

社区同意使用一种新的语法来指定关键路径:该路径以\开头。 看起来如下:

struct Conference {
    var name = ""
    let city: String
}

let nameKeyPath = \Conference.name
let wwdc = Conference(name: "WWDC", city: "San Jose")
wwdc[keyPath: nameKeyPath] // "WWDC"

nameKeyPath对象描述对name属性的引用。 然后可以将其用作该对象的下标。

如果您将变量从wwdc let更改为var ,则还可以通过key-path下wwdc修改特定的属性。

wwdc[keyPath: nameKeyPath] = "AltConf"
let name = wwdc[keyPath: nameKeyPath] // "AltConf"

单面射程

SE-0172建议添加新的前缀和后缀运算符,以避免在可以推断起始索引或终止索引时不必要地重复它们。 例如,如果要从第二个索引一直到最后一个索引下标一个数组,则可以按以下方式编写:

let numbers = [-2, -1, 0, 1, 2]
let positive = numbers[2..<numbers.endIndex]

以前,必须指定endIndex 。 现在,存在一个较短的语法:

let positive = numbers[2...]

或者,如果要以起始索引开始:

let negative = numbers[...1]

相同的语法也可以用于switch语句中的模式匹配。

通用下标

在Swift 4之前,需要使用下标来定义特定的返回值类型。 SE-0148提出了定义一个通用下标的可能性,该通用下标将根据定义的结果值来推断返回类型。 除了类型注释外,它的工作方式与以前几乎相同。

struct Conferences {
    let conferences: [String: Any]

    // Returns the conference models given its key.
    subscript<T>(key: String) -> T? {
        return conferences[key] as? T
  }
}
// Define the return type of the variable and access the object via subscript.
let thing: Conference? = conferences["WWDC"]

如您所见,在需要通过下标语法访问对象的情况下,这确实提高了对象的可读性。

类和子类型存在

迄今为止,Swift类型系统缺少的功能之一就是能够将类限制为特定协议。 此问题已在Swift 4中修复-由于SE-0156 ,您现在可以指定对象的类型及其必须遵循的协议。 例如,您可以使用以下语法编写一个方法,该方法采用的UIView符合Reloadable协议:

func reload(view: UIView & Reloadable) {
}

字典和集的改进

Dictionary和Set在Swift 4中也得到了很好的刷新。由于添加了一些实用程序方法,它们使用起来更加愉悦。

mapValues

词典现在具有一个mapValues方法来更改所有值,从而避免使用需要使用键值元组的通用map方法。

let conferences = ["WWDC": "Very Good", "AltConf": "Good", "Firebase Party": "Very Fun"]
// Map over all values in the dictionary.
let newConferences = conferences.mapValues { value in
    return value + " 👍"
}
filter返回类型

现在, filter方法将返回与您进行过滤的类型相同的对象。

// The type of this variable is [String: String]
let wwdc = conferences.filter { $0.key == "WWDC" }
字典查找的默认值

使用字典时,可以在使用下标语法时提供默认值,以避免以后再拆开可选值。

// Default value if key is not found.
let talkShow = conferences["The Talk Show", default: "🤷♂️"]
字典分组初始化器

最后,引入了Dictionary(grouping:)初始化程序,以通过根据一些条件对现有集合的元素进行分组来帮助创建新字典。

在以下示例中,我们通过将所有具有相同起始字母的conferences分组在一起来创建字典。 词典将为conferences集合中的每个起始字母都有一个键,每个值都包含以该字母开头的所有键。

let dictionary = Dictionary(grouping: conferences.values) { $0.uppercased().first! }

资源资源

如果您有兴趣深入了解Swift 4的新功能,那么这里有一些其他资源:

  • Swift的新功能-会议402-WWDC 2017
  • Apple Swift指南
  • Ole Begemann的Swift 4 Playground新功能
  • Swift 4迁移指南

结论

现在,您已经了解了Swift 4中的一些主要新功能,现在您可能正在争先恐后地开始使用它们,以帮助保持代码库的新鲜和干净。 开始编写新代码以利用有用的新功能,并考虑重构一些以前的代码以使其更简单易读。

无论您是刚刚开始使用基础知识还是想探索更高级的主题,我们都构建了完整的指南来帮助您学习Swift 。

翻译自: https://code.tutsplus.com/articles/whats-new-in-swift-4--cms-28939