Swift 3.0 中,会删除一个我们可能不太熟悉的行为, 就是将元组自动展开成函数的参数列表调用某个函数。这种语言特性可能会提供某些特殊的便捷,但也会带来很多麻烦。所以 3.0 中会将这个特性删除。我们一起来了解一下。
在开始之前,咱们先来了解一下这个特性到底是怎么回事,可能大家平时都基本用不到这个特性。所谓的元组展开是这样一个特性,假设我们有这样一个函数:
func foo(a : Int, b : Int) {}
你可以通过函数的参数列表定义,来调用这个函数:
foo(42, b : 17)
这种调用形式也是我们大多数情况下会这样用的。但函数的调用其实还有另外一种形式,也就是元组自动展开,官方给出的原词叫做 “implicit tuple splat”,具体到代码就是这样:
let x = (1, b: 2)
foo(x)
这次,我们先声明一个元组 x,这个元组的内容和 foo 函数的参数列表是一致的。 所以我们可以把这个元组 x 直接传递给 foo 函数,并且能够正常调用。
怎么样,这个特性很少有人注意到吧。我自己也是在看了官方文档之后才知道的~
那么为什么 Swift 3.0 这次要删除这个特性呢。 我们看了它的语法后是不是觉得还挺方便的呢,怎么又要删除了呢? 这点在官方文档中也有说明,虽然这个特性有它的方便的一面,但也会带来更多的问题。
比如,你在看代码的时候看到这样一个调用 foo(x)
,如果你不知道还会有元组扩展这个机制的话,是不是会认为这个函数只接收 1 个参数呢? 这样就非常容易给不了解这个特性的同学造成困扰。
除了这个之外,还会造成混淆,假如我这个函数就是要接收一个元组作为参数,那么这个调用该怎么正确的选择重载呢? 比如这样:
func foo(a : Int, b : Int) {}
func foo(a : (_,b: Int)) {}
这两个函数重载的参数列表是不一样的,但是他们都可以通过 foo(x)
这种方式来调用,就会造成混淆。
最后,这个特性还会对编译速度产生影响,毕竟多检测了一种语法嘛~
所以 Swift 核心团队在综合考虑之后,决定在 3.0 版本中去掉这个特性。这个提议在 SE-0029 号中,里面还说了一些后期方案,比如可以对这种元组展开做一个标识符:
foo(*x)
用星号代表这个参数是要进行元组展开的。这样就不会自动展开产生混淆了。从提案的讨论来看,这还只是建议。
总之呢,这个特性估计很少会被用到,我也是看了这个提案后才知道 Swift 之前版本还有这个特性,呵呵~,不过了解一下还是不错的。然后,就让它轻轻的走来,然后轻轻的离去吧~