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

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



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



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

结语

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

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

下一次,我们聊一聊和 SwiftUI 相关的另一个 Swift 新特性:Property Wrapper Types

转载于作者:面试官小健
链接:https://www.jianshu.com/p/349fe5b5c71e

小编这呢,给大家推荐一个优秀的iOS交流平台,平台里的伙伴们都是非常优秀的iOS开发人员,我们专注于技术的分享与技巧的交流,大家可以在平台上讨论技术,交流学习。欢迎大家的加入(想要进入的可加小编微信15673450590)。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 193,968评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,682评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,254评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,074评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 60,964评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,055评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,484评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,170评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,433评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,512评论 2 308
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,296评论 1 325
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,184评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,545评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,880评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,150评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,437评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,630评论 2 335

推荐阅读更多精彩内容

  • 136.泛型 泛型代码让你可以写出灵活,可重用的函数和类型,它们可以使用任何类型,受你定义的需求的约束。你可以写出...
    无沣阅读 1,432评论 0 4
  • 作者:刘铎本文为原创文章,转载请注明作者及出处 WWDC 2017 带来了很多惊喜。Swift 4 也伴随着 Xc...
    沪江技术学院阅读 31,844评论 7 127
  • 怎样才能维护好自己的健康,首先要掌握相关的如何维护健康知识。是什么原因导致我们得病,病因来源于哪儿?如果知道病...
    七色阳光l阅读 2,757评论 0 0
  • 2018年已经过去了,今天是2019年第一天,也是新的开始,新的目标新的生活,我也不怕什么了,今年我的目标是...
    水玉琴阅读 536评论 0 5
  • 后来你消失在我的视线, 忘了你我是如何相识? 忘了你我是如何别离? 我只知道我想念你了。。。 不知道你身在何方? ...
    清香百合1124阅读 349评论 1 7