SwiftUI 和 Swift 5.1 新特性之:不透明返回类型

栏目: Swift · 发布时间: 4年前

内容简介:今年 WWDC 最重要的关注点是什么?Swift!Swift 5.0 ABI 达到稳定,Swift 5.1 达到 Module Stability,预示着 Swift 进入了成熟期。苹果也开始认真地吃自己的狗食了,我们看到这届大会上推出了几个用 Swift 写的 iOS 框架,占篇幅最大的,无疑是 SwiftUI。为了这个框架写得6,苹果可以改语言,还不止一处。这次给大家介绍的是 Swift 5.1 在 protocol 上的改进:Opaque Result Type 不透明结果类型。这个特性增强了 Swi

今年 WWDC 最重要的关注点是什么?Swift!Swift 5.0 ABI 达到稳定,Swift 5.1 达到 Module Stability,预示着 Swift 进入了成熟期。苹果也开始认真地吃自己的狗食了,我们看到这届大会上推出了几个用 Swift 写的 iOS 框架,占篇幅最大的,无疑是 SwiftUI。为了这个框架写得6,苹果可以改语言,还不止一处。这次给大家介绍的是 Swift 5.1 在 protocol 上的改进:Opaque Result Type 不透明结果类型。这个特性增强了 Swift 泛型的能力,影响了 SwiftUI 的设计。

不透明结果类型新特性

先来看一段代码,它展现了原来 protocol 能力上的缺陷:

protocol Shape {}

struct Rectangle: Shape {}

struct Union<A: Shape, B: Shape>: Shape {
    var a: Shape
    var b: Shape
}

struct Transformed<S: Shape>: Shape {
    var shape: S
}

protocol GameObject {
    associatedtype ShapeType: Shape
    var shape: ShapeType { get }
}

struct EightPointedStar: GameObject {
    var shape: Union<Rectangle, Transformed<Rectangle>> {
        return Union(a:Rectangle(), b:Transformed(shape: Rectangle()))
    }
}
复制代码

缺陷有两方面:

  1. 上述代码是可以编译通过的,但是 EightPointedStar 的 shape 返回类型又臭又长,被暴露了出去;如果换成 Shape 则编译不通过,原因是 associatedtype ShapeType 要求必须指定具体的类型,而 Shape 不实现 Shape 本身。

  2. 假如 Shape 协议中含有 Self 或者 associatedtype,无法作为函数的返回参数。这是 Swift 泛型系统长久以来的一个问题。

而本文介绍的 Swift 5.1 Opaque Result Type 特性,解决了上述问题,它为 protocol 作为返回类型提供以下能力:

  1. 语法上隐藏具体类型,所以叫做不透明结果类型

  2. 强类型:类型参数不丢失

  3. 允许带有 Self 或者 associatedtype 的 protocol 作为返回类型

在 Swift 5.1 中,将返回类型改成 some + protocol 的形式:

struct EightPointedStar: GameObject {
    var shape: some Shape {
        return Union(a:Rectangle(), b:Transformed(shape: Rectangle()))
    }
}
复制代码

这类的泛型特性也被称作“反向泛型”,因为具体的类型参数是由“实现部分”指定并隐藏起来的,而一般的泛型是由“调用者”所指定的。

上面这个例子中:语法上隐藏具体类型很明显,再举一个例子说明其它 2 个特性:

func foo<T: Equatable>(x: T, y: T) -> some Equatable {
    let condition = x == y
    return condition ? 42 : 11
}

let x = foo("apples", "bananas")
let y = foo("apples", "oranges")

print(x == y) // 这里可以被调用是因为泛型系统保留了强类型
复制代码

这个例子显示了不透明结果类型的三个特性:既对外隐藏了具体的 Equatable 类型;又保留了强类型(使得 x == y)可以比较;还支持了 Equatable 这个带 Self 的泛型约束。

不透明结果类型对于函数实现有一个增强的要求:函数实现必须返回同一个具体类型,以上述代码为例:不能返回 Equatable 或者是 不同类型的 Equatable 的实现。

这里还有一个小问题:既然 x 和 y 可以直接比较,那么它们可否直接赋值给 var i: Int 呢?答案是对于静态类型系统是不可以的,它保留了 some Equatable 的具体类型隐藏功能,但是如果使用动态类型判断 as? Int,则可以转换成 Int。

SwiftUI 上的应用

SwiftUI 和 Swift 5.1 新特性之:不透明返回类型

SwiftUI 的一大特点是高度可组合,View 的唯一属性 body 是另一个满足 View 约束的具体 View 类型,我们在这里看到了组合以及递归两个特性。下面来看一个具体的 View 类型:

SwiftUI 和 Swift 5.1 新特性之:不透明返回类型

这个 OrderCell 使用了不透明返回类型的特性,对外隐藏了具体类型 HStack。我们看到 OrderCell 的类型它是一个递归的定义。

SwiftUI 和 Swift 5.1 新特性之:不透明返回类型

所有的递归定义都需要一个终止条件,于是就有了以下这些 Primitive Views:

SwiftUI 和 Swift 5.1 新特性之:不透明返回类型

结语

很高兴看到苹果终于开始提供 iOS 操作系统中的 Swift-Only 的 Framework,它对于 Swift 的推广和语言改进有进一步的促进作用。

另外,我们也要注意到这个特性增加了 Swift ABI 的能力,需要最新的 runtime 才能运行。

参考资料:Swift Evolution 0244,WWDC 19 What's New in Swift,SwiftUI Essentials。

扫描下方二维码,关注“面试官小健”

SwiftUI 和 Swift 5.1 新特性之:不透明返回类型

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Code

Code

Charles Petzold / Microsoft Press / 2000-10-21 / USD 29.99

Paperback Edition What do flashlights, the British invasion, black cats, and seesaws have to do with computers? In CODE, they show us the ingenious ways we manipulate language and invent new means of ......一起来看看 《Code》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

CSS 压缩/解压工具
CSS 压缩/解压工具

在线压缩/解压 CSS 代码

HTML 编码/解码
HTML 编码/解码

HTML 编码/解码