swift 中有一个不透明类型的概念,在 SwiftUI 开发中经常看到的 var body: some View 正是基于这个概念。这篇文章来研究下 some 的作用。
看下面的代码
protocol Shape {
func describe() -> String
}
struct Square: Shape {
func describe() -> String {
return "I'm Square"
}
}
struct Circle: Shape {
func describe() -> String {
return "I'm circle"
}
}
func makeShape() -> some Shape {
return Circle()
}
let shape = makeShape()
print(shape.describe())
复制代码
上面代码定义一个 protocol ,并且有两个 struct 实现了该协议,some 的使用出现在 makeShape 函数的返回值中,这里使用 some 表示:该函数的返回值是实现了 protocol 协议的某一个类型,具体是什么类型不知道。some 的「不透明类型」指的就是:没有明明白白告诉你具体是什么类型的,只是说明了这个类型和 Shape protocol 有关。
但是,makeShape 的返回值改成 Shape 仍然可以运行:
func makeShape() -> Shape {
return Circle()
}
复制代码
那 some 和 protocol 有啥区别?
我们知道 protocol 中可以有 associatedtype ,基于上面的代码,引入 associatedtype 看看。
protocol Shape {
associatedtype ColorType
var color: ColorType { get }
func describe() -> String
}
struct Square: Shape {
var color: String
typealias ColorType = String
func describe() -> String {
return "I'm Square"
}
}
struct Circle: Shape {
var color: Int
typealias ColorType = Int
func describe() -> String {
return "I'm circle"
}
}
func makeShape() -> some Shape {
return Circle(color: 255)
}
let shape = makeShape()
print(shape.describe())
复制代码
现在 Shape 引入了 associatedtype,每个实现 Shape protocol 的 struct 都需要明确 ColorType 的具体类型。现在 makeShape 的返回值如果仍然是 Shape 就会报错:Protocol 'Shape' can only be used as a generic constraint because it has Self or associated type requirements。原因在于 swift 不知道返回值 Shape 的 associatedtype 是什么类型。在引入 some 之后,swift 可以从 return 的类型推断出 associatedtype 为 Int 类型。
总结一下:为什么需要 some?因为 protocol 中有 associatedtype 时,使用 protocol 的地方无法确定 associatedtype 的类型,那么这个时候使用 some 修饰,表示:这个地方是一个实现了 protocol** 的类型,具体是什么类型尚未确定**。
最后,来理解 SwiftUI 中 some 的使用。
var body: some View {
VStack(alignment: .leading) {
Text("hello")
Text("world")
}
}
复制代码
这里,body 属性的具体类型为 VStack<TupleView<(Text, Text)>>,随着布局深入,那么类型就会越来越复杂。所以这里使用 some View 来代替,告诉 swift:body 是一个实现了 View protocol 的结构体,具体是什么类型不清楚,你可以在编译的时候通过返回值推断出来。
























![[桜井宁宁]COS和泉纱雾超可爱写真福利集-一一网](https://www.proyy.com/skycj/data/images/2020-12-13/4d3cf227a85d7e79f5d6b4efb6bde3e8.jpg)

![[桜井宁宁] 爆乳奶牛少女cos写真-一一网](https://www.proyy.com/skycj/data/images/2020-12-13/d40483e126fcf567894e89c65eaca655.jpg)