苹果爸爸在
3.29
正式发布了
Swift 4.1
版本,这个版本从代码层面兼容了
Swift 4
,所以如果用
Xcode
中的
Swift Migrator
来迁移工程的话,不会影响到原来的代码。
本文主要整理了
raywenderlich
上的
What’s New in Swift 4.1?
和 官方博客上的内容,简要介绍了
Swift 4.1
相关的一些新特性。
1
支持元素类型为
Optional
的集合比较,或者底层类型为
Optional
的
Optional
比较,只要内层
Optional
的底层类型实现了
Equatable
协议。
[SE-0143]
let array1 = [1, nil, 2, nil, 3, nil]
let array2 = [1, nil, 2, nil, 3, nil]
array1 == array2 // true
let optional1: Optional<Optional<Int>> = 1
let optional2: Optional<Optional<Int>> = 1
optional1 == optional2 // true
2
支持多维数组直接比较,只要底层类型实现了
Equatable
协议。
[SE-0143]
let arrayOfArray1 = [[1, 2, 3]]
let arrayOfArray2 = [[1, 2, 3]]
arrayOfArray1 == arrayOfArray2 // true
3
如果集合(
Array
,
Dictionary
,
Set
)和
Optional
的元素符合
Codable
协议,则集合和
Optional
本身也符合
Codable
协议。
let cosmin = Student(firstName: "Cosmin", grade: 10)
let george = Student(firstName: "George", grade: 9)
let encoder = JSONEncoder()
let students = [cosmin, george]
do {
try encoder.encode(students)
} catch {
print("Failed encoding students array: \(error)")
}
4
在
JSON
编解码时,可以在 对象/结构体的
Camel Case
格式的属性名和
JSON
的
Snake Case
格式的
key
之间转换,只需要设置编解码对象的
keyEncodingStrategy
属性。
let cosmin = Student(firstName: "Cosmin", grade: 10)
let george = Student(firstName: "George", grade: 9)
let encoder = JSONEncoder()
let students = [cosmin, george]
var jsonData = Data()
encoder.keyEncodingStrategy = .convertToSnakeCase
encoder.outputFormatting = .prettyPrinted
do {
jsonData = try encoder.encode(students)
} catch {
print(error)
}
if let jsonString = String(data: jsonData, encoding: .utf8) {
print(jsonString)
}
//[
// {
// "grade" : 10,
// "first_name" : "Cosmin"
// },
// {
// "grade" : 9,
// "first_name" : "George"
// }
//]
将
JSON
字符串解码为对象/结构体时,也有类似的操作。
5
struct
如果要符合
Equatable
和
Hashable
协议,则编辑器会默认为
struct
合成
Equatable
和
Hashable
的代码,只要其所有的属性都符合
Equatable
和
Hashable
协议,不再需要我们去写一大堆的模板代码,减少了我们的代码量。
[SE-0185]
struct Country: Hashable {
let name: String
let capital: String
// 默认实现了 static func ==(lhs: Country, rhs: Country) -> Bool 和 var hashValue: Int
// 不再需要我们自己写代码
}
6
枚举类型如果要符合
Equatable
和
Hashable
协议,编译器也会默认合成了
Equatable
和
Hashable
的实现,同上。
[SE-0185]
7
扩展
Key-path
表达式在标准库中的使用范围。让标准库中所有的索引类型都符合
Hashable
协议,这样,
[Int]
、
String
和所有其它标准集合使用
key-path
下标时,表现都是一样的。
[SE-0188]
let cos = "Cosmin"
let newPath = \String.[cos.startIndex]
let initial = cos[keyPath: newPath] // C
8 支持协议中关联类型的递归约束。 [SE-0157]
protocol Phone {
associatedtype Version
associatedtype SmartPhone: Phone where SmartPhone.Version == Version, SmartPhone.SmartPhone == SmartPhone
}
9
移除了协议中的
weak
和
unowned
。
[SE-0186]
class Key {}
class Pitch {}
// Swift 4
protocol Tune {
unowned var key: Key { get set }
weak var pitch: Pitch? { get set }
}
// Swift 4.1