Swift 5.2 闭包中的元组解构行为不一致

Swift 5.2 tuple destructuring in closure has inconsistent behaviors

我 运行 在 Swift 5.2 中遇到了一个奇怪的元组解构问题。 我认为元组解构从前一段时间起就不能在闭包参数内工作。 事实上,以下内容不起作用:

let expected: ((Int, Int)) -> Void = { a, b in  // does not compile
    print(a, b)
}

但是,我注意到以下所有工作:

func weird(closure: @escaping ((Int, Int)) -> Void) {
    closure((1, 3))
}

// I can understand this
weird { print([=12=].0 + [=12=].1) }
weird { a, b in print(a + b) }

// Surprise!
weird { print([=12=] + ) }
weird { p in print(p.0 + p.1) }

最后两个示例在 Swift 5.2 之前是否有效?这种行为是否记录在某处?

与这个提案有关,在Swift4.0中曾经被采纳

SE-0110 Distinguish between single-tuple and multiple-argument function types

因此,您的两个示例(虽然不是最后两个)在 Swift 的某个版本中导致了错误,但是 Swift 团队在该实现中发现了一些不可接受的回归。 Additional Commentary

并且由于 Swift 的某个版本(我不记得确切的版本,它可能是 4.0.x 或 4.1),您可以将两个参数闭包传递给参数采用单个元组的函数类型。

最近,这个异常被确认为 SE-0110 的一部分,如果需要更多的修改,将提出一个新的提案,并通过通常的 Swift 进化过程。

Update on SE-0110 and SE-0155

the original proposal as reviewed did not include the special-case conversion from (T, U, ...) -> V to ((T, U, ...)) -> V for function arguments. In response to community feedback, this conversion was added as part of the Core Team's acceptance of the proposal.

Swift 书中可能没有对此行为的明确解释,但肯定是 记录