Swift 演进参数包提案以动机部分开始,其中引用了以下一些熟悉的丑陋之处:
func < (lhs: (), rhs: ()) -> Bool
func < <A, B>(lhs: (A, B), rhs: (A, B)) -> Bool where A: Comparable, B: Comparable
func < <A, B, C>(lhs: (A, B, C), rhs: (A, B, C)) -> Bool where A: Comparable, B: Comparable, C: Comparable
这里的问题是,为了实现元组的比较,我们必须对 2 元组实现它,对 3 元组再次实现它,依此类推。此外,这种重复意味着我们必须在达到某个任意最大元组大小(6 元组)后放弃。
我的问题是:Swift 参数包究竟如何解决这个问题?查看 Swift 6 的标头,我没有看到 tuple 的声明<
与早期的 Swift 版本相比有任何变化。(事实上,我没有看到 Swift 标头中使用参数包,就是这样。)无论如何(更重要的是),参数包根本不是关于 tuple 的;它们是关于variadics 的。
因此我可以立即看到我们如何实现两个 Comparable 值的可变列表之间的比较:
func isLessThan<each T: Comparable>(lhs: repeat each T, rhs: repeat each T) -> Bool {
for pair in repeat (each lhs, each rhs) {
if pair.0 >= pair.1 {
return false
}
}
return true
}
我们可以这样调用它:
let result = isLessThan(lhs: 1, "a", rhs: 2, "b")
很好——但这些不是元组。它们是可变参数列表。问题的根源在于没有办法动态地创建可变参数列表:您无法将元组(或序列)转换为可变参数列表。
那么参数包如何解决动机问题呢?