今年 WWDC 最重要的關(guān)注點(diǎn)是什么胰锌?Swift恶阴!Swift 5.0 ABI 達(dá)到穩(wěn)定戒突,Swift 5.1 達(dá)到 Module Stability,預(yù)示著 Swift 進(jìn)入了成熟期茅逮。蘋(píng)果也開(kāi)始認(rèn)真地吃自己的狗食了,我們看到這屆大會(huì)上推出了幾個(gè)用 Swift 寫(xiě)的 iOS 框架判哥,占篇幅最大的献雅,無(wú)疑是 SwiftUI。為了這個(gè)框架寫(xiě)得6姨伟,蘋(píng)果可以改語(yǔ)言惩琉,還不止一處。這次給大家介紹的是 Swift 5.1 在 protocol 上的改進(jìn):Opaque Result Type 不透明結(jié)果類型夺荒。這個(gè)特性增強(qiáng)了 Swift 泛型的能力瞒渠,影響了 SwiftUI 的設(shè)計(jì)。
不透明結(jié)果類型新特性
先來(lái)看一段代碼技扼,它展現(xiàn)了原來(lái) 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.上述代碼是可以編譯通過(guò)的伍玖,但是 EightPointedStar 的 shape 返回類型又臭又長(zhǎng),被暴露了出去剿吻;如果換成 Shape 則編譯不通過(guò)窍箍,原因是 associatedtype ShapeType 要求必須指定具體的類型,而 Shape 不實(shí)現(xiàn) Shape 本身丽旅。
2.假如 Shape 協(xié)議中含有 Self 或者 associatedtype椰棘,無(wú)法作為函數(shù)的返回參數(shù)。這是 Swift 泛型系統(tǒng)長(zhǎng)久以來(lái)的一個(gè)問(wèn)題榄笙。
而本文介紹的 Swift 5.1 Opaque Result Type 特性邪狞,解決了上述問(wèn)題,它為 protocol 作為返回類型提供以下能力:
1.語(yǔ)法上隱藏具體類型茅撞,所以叫做不透明結(jié)果類型
2.強(qiáng)類型:類型參數(shù)不丟失
3.允許帶有 Self 或者 associatedtype 的 protocol 作為返回類型
在 Swift 5.1 中帆卓,將返回類型改成 some + protocol 的形式:
struct EightPointedStar: GameObject {
var shape: some Shape {
return Union(a:Rectangle(), b:Transformed(shape: Rectangle()))
}
}
這類的泛型特性也被稱作“反向泛型”,因?yàn)榫唧w的類型參數(shù)是由“實(shí)現(xiàn)部分”指定并隱藏起來(lái)的米丘,而一般的泛型是由“調(diào)用者”所指定的剑令。
上面這個(gè)例子中:語(yǔ)法上隱藏具體類型很明顯,再舉一個(gè)例子說(shuō)明其它 2 個(gè)特性:
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) // 這里可以被調(diào)用是因?yàn)榉盒拖到y(tǒng)保留了強(qiáng)類型
這個(gè)例子顯示了不透明結(jié)果類型的三個(gè)特性:既對(duì)外隱藏了具體的 Equatable 類型拄查;又保留了強(qiáng)類型(使得 x == y)可以比較吁津;還支持了 Equatable 這個(gè)帶 Self 的泛型約束。
不透明結(jié)果類型對(duì)于函數(shù)實(shí)現(xiàn)有一個(gè)增強(qiáng)的要求:函數(shù)實(shí)現(xiàn)必須返回同一個(gè)具體類型堕扶,以上述代碼為例:不能返回 Equatable 或者是 不同類型的 Equatable 的實(shí)現(xiàn)碍脏。
這里還有一個(gè)小問(wèn)題:既然 x 和 y 可以直接比較癣疟,那么它們可否直接賦值給 var i: Int 呢?答案是對(duì)于靜態(tài)類型系統(tǒng)是不可以的潮酒,它保留了 some Equatable 的具體類型隱藏功能睛挚,但是如果使用動(dòng)態(tài)類型判斷 as? Int,則可以轉(zhuǎn)換成 Int急黎。
SwiftUI 上的應(yīng)用
SwiftUI 的一大特點(diǎn)是高度可組合扎狱,View 的唯一屬性 body 是另一個(gè)滿足 View 約束的具體 View 類型,我們?cè)谶@里看到了組合以及遞歸兩個(gè)特性勃教。下面來(lái)看一個(gè)具體的 View 類型:
這個(gè) OrderCell 使用了不透明返回類型的特性淤击,對(duì)外隱藏了具體類型 HStack。我們看到 OrderCell 的類型它是一個(gè)遞歸的定義故源。
所有的遞歸定義都需要一個(gè)終止條件污抬,于是就有了以下這些 Primitive Views:
結(jié)語(yǔ)
很高興看到蘋(píng)果終于開(kāi)始提供 iOS 操作系統(tǒng)中的 Swift-Only 的 Framework,它對(duì)于 Swift 的推廣和語(yǔ)言改進(jìn)有進(jìn)一步的促進(jìn)作用绳军。
另外印机,我們也要注意到這個(gè)特性增加了 Swift ABI 的能力,需要最新的 runtime 才能運(yùn)行门驾。
下一次射赛,我們聊一聊和 SwiftUI 相關(guān)的另一個(gè) Swift 新特性:Property Wrapper Types
轉(zhuǎn)載于作者:面試官小健
鏈接:http://www.reibang.com/p/349fe5b5c71e
小編這呢,給大家推薦一個(gè)優(yōu)秀的iOS交流平臺(tái)奶是,平臺(tái)里的伙伴們都是非常優(yōu)秀的iOS開(kāi)發(fā)人員楣责,我們專注于技術(shù)的分享與技巧的交流,大家可以在平臺(tái)上討論技術(shù)聂沙,交流學(xué)習(xí)秆麸。歡迎大家的加入(想要進(jìn)入的可加小編微信15673450590)。