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

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

内容简介:今年 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 新特性之:不透明返回类型

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

查看所有标签

猜你喜欢:

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

游戏编程模式

游戏编程模式

Robert Nystrom / GPP翻组 / 人民邮电出版社 / 2016-9-1 / 61.4

游戏开发一直是热门的领域,掌握良好的游戏编程模式是开发人员的应备技能。本书细致地讲解了游戏开发需要用到的各种编程模式,并提供了丰富的示例。 全书共分20章,通过三大部分内容全面介绍了与游戏编程模式相关的各类知识点。首部分介绍了基础知识和框架;第二部分深入探索设计模式,并介绍了模式与游戏开发之间的关联;第三部分介绍了13种有效的游戏设计模式。 本书提供了丰富的代码示例,通过理论和代码示例......一起来看看 《游戏编程模式》 这本书的介绍吧!

随机密码生成器
随机密码生成器

多种字符组合密码

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具