正如
Swift官方博客所说,Swift 4.2 是为 Swift 5 的 ABI 稳定性做准备,它包含了一些底层 ABI 的变化。我们看 swift-evolution 中的 proposal 清单,在 4.2 中已经实现了其中一些 proposal。
大纲
- Bool.toggle(
Bool
值反转)
- Sequence and Collection algorithms(新增了序列和集合相关的操作方法)
- Enumerating enum cases(返回枚举属性集合)
- Random numbers(生成随机数)
- Hashable redesign(对
Hashable
的重新设定)
- Conditional conformance enhancements(条件一致性的增强)
- Dynamic member lookup(动态成员查找)
#error and #warning
- MemoryLayout.offset(of:)
- @inlinable
- withUnsafePointer(to::) 和 withUnsafeBytes(of::)
环境要求
Xcode 10 beta
或者Swift 4.2
1. Bool.toggle
顾名思义,toggle即是Bool新增的一个值反转方法。如果您需要在嵌套数据结构的深处切换布尔值,这尤其有用,因为您不必在赋值的两侧重复相同的表达式。
apple官方文档
例如:
struct Layer {
var isHidden = false
}
struct View {
var layer = Layer()
}
var view = View()
// 之前:
view.layer.isHidden = !view.layer.isHidden
view.layer.isHidden // true
// 现在,是不是方便了许多
view.layer.isHidden.toggle() // false
2. Sequence and Collection algorithms (新增了序列和集合相关的算法)
(1). 序列新增allSatisfy
方法
allSatisfy
是为序列新增的算法, 当且仅当序列中的所有元素都满足给定条件时,allSatisfy才返回true。 这个函数通常只用函数式语言调用。
apple官方文档
let digits = 0...9
let areAllSmallerThanTen = digits.allSatisfy { $0 < 10 }
areAllSmallerThanTen // 输出:true
let areAllEven = digits.allSatisfy { $0 % 2 == 0 }
areAllEven // 输出:false
(2). 新增last(where:)
,lastIndex(where:)
, and lastIndex(of:)
方法
给序列新增了
last(where:)
方法,给集合(字符串)新增了
lastIndex(where:)
,
and lastIndex(of:)
方法。
apple官方文档
let lastEvenDigit = digits.last { $0 % 2 == 0 }
lastEvenDigit // 输出:8
let text = "Vamos a la playa"
let lastWordBreak = text.lastIndex(where: { $0 == " " })
let lastWord = lastWordBreak.map { text[text.index(after: $0)...] }
lastWord // 输出:playa
text.lastIndex(of: " ") == lastWordBreak // true
(3)、把 index(of:)
和 index(where:)
更名为: firstIndex(of:)
和 firstIndex(where:)
let firstWordBreak = text.firstIndex(where: { $0 == " " })
let firstWord = firstWordBreak.map { text[..<$0] }
firstWord // 输出:Vamos
3. Enumerating enum cases
enum新增了返回集合属性的方法:编译器可以自动为枚举生成
allCases
属性,为您提供始终最新的枚举列表。 您所要做的就是使您的枚举符合新的
CaseIterable
协议。
enum Terrain: CaseIterable {
case water
case forest
case desert
case road
}
Terrain.allCases // 输出:water, forest, desert, road
Terrain.allCases.count // 输出:4
注意,自动合成仅适用于没有关联值的枚举。 因为关联值意味着枚举可能具有可能无限数量的可能值。
如果所有可能值的列表都是有限的,您可以手动实现协议。 举个例子:这里都是遵守了CaseIterable协议条件一致的可选类型的值。
apple官方文档
extension Optional: CaseIterable where Wrapped: CaseIterable {
public typealias AllCases = [Wrapped?]
public static var allCases: AllCases {
return Wrapped.allCases.map { $0 } + [nil]
}
}
// 注意:这不是可选绑定
Terrain?.allCases // 输出:water, forest, desert, road,nil
Terrain?.allCases.count // 输出:5
4. Random numbers
使用随机数在Swift中一直不是很友好,因为(a)你必须直接调用C语言的API来实现,(b)没有一个好的跨平台的生产随机数的API。
(1)、生成随机数
在Swift4.2中,苹果将随机数生成添加到标准库中。
Apple官方文档
支持所有数字类型的生成随机数方法
random(in:)
,它返回给定范围内的随机数(默认情况下均匀分布):
Int.random(in: 1...1000) // 输出:432
UInt8.random(in: .min ... .max) // 输出:226
Double.random(in: 0..<1) // 输出:0.9219874372193483
同时,这个api也很好的避免了modulo bias偏差的发生。
func coinToss(count tossCount: Int) -> (heads: Int, tails: Int) {
var tally = (heads: 0, tails: 0)
for _ in 0..
(2)、返回集合(如:字符串)的随机值
如果一个集合使用randomElement
方法,且集合为空,则返回的值为nil
。
let emotions = "