Swift 5.4中的链式隐式成员表达式介绍及实例

260 阅读2分钟

Swift 5.4 中的新内容: 隐式成员表达式(也称为 "点语法")现在甚至可以在访问此类表达式结果上的属性或方法时使用,只要最终返回类型保持不变。

这在实践中意味着,每当我们使用静态API创建一个对象或值,或者引用一个枚举案例时,我们现在可以直接调用该实例上的方法或属性,而编译器仍然能够推断出我们所指的是什么类型。

举个例子,当使用作为系统一部分的内置静态API创建一个UIColor 实例时,我们现在可以很容易地修改这种颜色的alpha分量,而不需要在这样的情况下明确引用UIColor 本身。

// In Swift 5.3 and earlier, an explicit type reference is always
// required when dealing with chained expressions:
let view = UIView()
view.backgroundColor = UIColor.blue.withAlphaComponent(0.5)
...

// In Swift 5.4, the type of our expression can now be inferred:
let view = UIView()
view.backgroundColor = .blue.withAlphaComponent(0.5)
...

当然,上述方法在使用我们自己的静态API时也是有效的,例如,我们通过使用扩展添加的任何自定义UIColor 定义。

extension UIColor {
    static var chiliRed: UIColor {
        UIColor(red: 0.89, green: 0.24, blue: 0.16, alpha: 1)
    }
}

let view = UIView()
view.backgroundColor = .chiliRed.withAlphaComponent(0.5)
...

不过,也许更有趣的是,这种新的能力在API设计方面打开了哪些大门。作为一个例子,在 "Swift中的轻量级API设计 "中, 我们看了以下API风格,它涉及到用静态方法和属性扩展一个结构,使我们能够以非常 "枚举 "的方式使用它。

extension ImageFilter {
    static var dramatic: Self {
        ImageFilter(
            name: "Dramatic",
            icon: .drama,
            transforms: [
                .portrait(withZoomMultipler: 2.1),
                .contrastBoost,
                .grayScale(withBrightness: .dark)
            ]
        )
    }
}

当使用Swift 5.4(或未来的更高版本)时,我们现在可能会添加类似以下的东西--这让我们可以通过连接两个ImageFilter 实例来轻松组合它们的transforms

extension ImageFilter {
    func combined(with filter: Self) -> Self {
        var newFilter = self
        newFilter.transforms += filter.transforms
        return newFilter
    }
}

有了上述内容,我们现在就可以使用同样轻量级的点语法来处理动态组合的过滤器,而我们以前只能在引用单个预定义的过滤器时使用。

let filtered = image.withFilter(.dramatic.combined(with: .invert))