本文正在参加「金石方案」

什么是Opaque Types

Opaque Types 是在 Swift5.7 新增加的一个特性。主要是和 Protocol 来搭配运用,用来界说函数中的参数类型。它的作用便是隐藏参数的详细类型,从而使代码变得愈加通用,削减冗余代码。废话不多说,下面来看一看它怎么运用。

怎么运用

假定咱们有一个界说动物行为的 Protocol Behavior,有两个动物类 Cat 和 Dog 恪守了该协议:

protocol Behavior {
    func run()
}
struct Cat: Behavior {
    func run() {
        print("Cat run")
    }
}
struct Dog: Behavior {
    func run() {
        print("Dog run")
    }
}

如果咱们想测试一下 run 的功能,可以经过运用 Opaque Types 来界说函数的参数,从而使测试函数可以接受 Cat 和 Dog 的实例目标:

func testRun(animal: some Behavior) {
    animal.run()
}
let cat = Cat()
let dog = Dog()
testRun(animal: cat) // Cat run
testRun(animal: dog) // Dog run

从上述代码可以看到,animal 的类型为 some Behavior。经过 some 关键字声明的类型便是所谓的 Opaque Types,some Behavior 的意思便是任何恪守了 Behavior 的类的实例目标。

看到这里,或许有的读者就会发现这个不是什么新奇的特性啊,这不就相当于泛型嘛?有这种想法的读者稍安勿躁,下面就来讲一下为什么要运用 Opaque Types。

为什么要运用

可读性更强

首要,下面的三个函数从语法层级上来说都是等价的:

func testRun(animal: some Behavior) {
    animal.run()
}
func testRun1<A: Behavior>(animal: A) {
    animal.run()
}
func testRun2<A>(animal: A) where A: Behavior {
    animal.run()
}

为什么运用的第一个原因便是:运用 some 界说愈加清晰,使得代码可读性更高更简单理解。 上面的代码界说比较简单,或许感觉不同不大,咱们看看下面的代码应该会有更深的领会:

func encodeAnyDictionaryOfPairs(_ dict: [some Hashable & Codable: Pair<some Codable, some Codable>]) -> Data
func encodeAnyDictionaryOfPairs<_T1: Hashable & Codable, _T2: Codable, _T3: Codable>(_ dict: [_T1: Pair<_T2, _T3>]) -> Data

功能更好

还有一个重要的原因便是当 Opaque Types 作为回来值类型时它的约束比 Protocol 类型愈加严格,比如下面的代码:

func testReturn(isCat: Bool) -> some Behavior { // 编译报错
    if isCat {
        return Cat()
    } else {
        return Dog()
    }
}
func testReturn1(isCat: Bool) -> Behavior { // 正常编译不会报错
    if isCat {
        return Cat()
    } else {
        return Dog()
    }
}

当编译器编译 testReturn 函数时,会报以下错误:

学习 Swift 中 Opaque Types

而 testReturn1 则不会报错。由于对于 Protocol 作为回来值来讲,不会强制要求一切分支回来同一类型的目标。

当 Opaque Types 做回来值时,虽然回来值的详细类型不做约束,即任何恪守 Behavior 协议的目标都可以,但一切的分支回来有必要为同一类型的目标,即或许回来 Cat,又或许回来 Dog 是不允许的。

这样做的优点便是代码的功能更好,由于咱们从底层约束了回来类型有必要是同一类型,所以编译器处理起来会更快。

任何的事物都有两面性,Opaque Types 也不破例。最后咱们来了解一下它的约束。

运用的约束

  • 不能用于可变参数的声明
  • 不用用于匿名函数的声明

总结

本篇文章,首要讲解了什么是 Opaque Types,然后又了解了它的运用方法,接着学习了它的优点:可读性更高;功能更好。最后说明了一下它的约束。 期望咱们看完这篇文章,能在项目中多多实践。

参考链接

  • Apple Document
  • Swift evolution
  • understanding some and any