swift官方文档_关于 Swift 的 Opaque Type,如 some View

358695500c011788171a1239290b0aa0.png

Swift 协议的一个强大之处,在于它可以作为类型约束;另一个强大之处,是 associated type,让协议可以实现一定程度的范型。

但这两个优势是互相矛盾的,如果协议内部有 associated type(或者协议引用了 Self 类型,因为这样其实也是一种 associated type 行为),这个协议就不能用于类型约束了。

下例会报错:Protocol 'Vehicle' can only be used as a generic constraint because it has Self or associated type requirements

protocol Vehicle {
    associatedtype FuelType: Fuel
}

func getVehicle() -> Vehicle {
    someone.vehicle
}

于是 Swift 引入了 some 关键词,或者说引入了 Opaque Type(不透明类型),总之此处加上 some 就不再报错了:

protocol Vehicle {
    associatedtype FuelType: Fuel
}

func getVehicle() -> some Vehicle {
    someone.vehicle
}

Opaque Type 只能作为变量类型或者函数返回值类型来使用,其他场景,比如作为函数的参数,就行不通,比如下例无论有没有 some 都无法通过编译:

func drive(_ vehicle: /* some */ Vehicle) {
    // ...
}

因为这里应该用 Generic(范型),而不是 Opaque Type:

func drive<V: Vehicle>(_ vehicle: V) {
    // ...
}

Generic 同样也可以解决方法返回值不能用类型约束的问题:

func drive<V: Vehicle>(_ vehicle: V) -> V {
    // ...
    // return ...
}

那么 Generic 和 Opaque Type 是否在职能上重叠了呢?


Opaque Type 与 Generic 的关系 / 区别

之前写过一篇相关的文章:

孙一萌:Protocol Oriented: Swift 协议陷阱之 Associated Type​zhuanlan.zhihu.com
9762e8c20f9e7d5b9446cea306c0f2be.png

今天首先贴出 关于 Opaque Types 的官方文档。

文档阐述了 Opaque Type 的设计初衷,以及它与 Generic 如何相辅相成。

套用到本例中,Opaque Type 和 Generic 都解决了协议无法作为类型约束的问题,但它们解决问题的方式是截然相反的,或者说它们的思想是有区别的。

Generic 让调用者决定参数或者返回值的类型。比如上面的 drive(_:) 方法,定义的时候只规定了参数必须遵从 Vehicle,并没有具体安排是哪种类型。具体是什么类型,完全由传入的变量决定:

func drive<V: Vehicle>(_ vehicle: V) {
    // ...
}

func example() {
    let car = GasolineCar()
    drive(car)
}

Opaque Type 是让方法本身决定返回的类型。比如 getVehicle() -> some Vehicle,调用者完全不知道方法会返回什么类型的值,只知道它一定遵从 Vehicle

func getVehicle() -> some Vehicle {
    someone.vehicle
}

func example() {
    let car = getVehicle()
    // ...
}

我们可以把它们结合起来用,让协议更强大,功能更加完整:

func getVehicle() -> some Vehicle {
    someone.vehicle
}

func drive<V: Vehicle>(_ vehicle: V) {
    // ...
}

func example() {
    let car = getVehicle()  // 1
    drive(car)  // 2
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值