Swift 5.2 Released!
SE-0249:将Key Path表达式作为函数:(Root)->Value
// 已知结构体
struct User {
let email: String
let isAdmin: Bool
}
生成一个邮箱地址的数组,过滤管理员,管理员数组
users.map { $0.email }
users.filter { $0.isAdmin }
users.compactMap { $0.isAdmin }
采用新的表达式:\Root.value
users.map(\.email)
users.filter(\.isAdmian)
语法解释:\Root.value相当于{$0[keyPath: \Root.value]}
users.map(\.email) === user.map { $0[keyPath: \User.email] }
语法注意:\Root.value是方法(Root)->Value的缩写,当使用临时变量时:
let kp = \User.email // 错误❌
let kp: (User) -> String = \User.email // 正确
let kp = \User.email as (User) -> String // 正确
users.map(kp)
编译器做了什么?
let kp: (User) -> String = \User.email // 代码
let kp: (User) -> String = { kp in { root in root[keyPath: kp] } }(\User.email) // 编译器后的代码
swift为啥添加该语法?
This is a purely additive change and has no impact.//
SE-0253:静态方法自定义
callAsFunction:
struct Adder {
var base: Int
func callAsFunction(_ x: Int) -> Int {
return base + x
}
func callAsFunction
(_ x: T, bang: Bool) throws -> T where T: BinaryInteger { if bang { return T(Int(exactly: x)! + base) }
else { retuurn T(Int(truncatingIfNeeded: x) + base) }
}
}
let add = Adder(base: 3)
add(10) // => 13
try add(4, bang: true) // => 5
subscript:
struct Polynomial {
let coefficients: [Float]
}
extension Polynomial {
subscript(input: Float) -> Float {
var result: Float = 0
for (i, c) in coefficients.enumerated() {
result += c * pow(input, Float(i))
}
return result
}
}
let polynomial = Polynomial(coefficients: [2, 3, 4])
print(polynomial.evaluated(at: 2)) // => 24
与闭包结合:类似于代理
struct BoundClosure
()>: () -> () { var function: F
var value: T
func callAsFunction() { return function(value) }
}
let f = BoundClosure({ print($0) }, x) // instantiates BoundClosure<(underlying type of closure), Int>
f() // invokes call on BoundClosure
提高编译结果准确性:错误代码提示更准确
优化代码不全:代码提示更人性化
优化编译算法
· Whole Module (typically used for Release builds)
· Incremental (typically used for Debug builds)