我正在尝试理解 Swift 中的参数标签并使用以下代码示例:
func getGreetFn(greeting: String) -> (String) -> Void {
func greetFn(person: String) {
print("\(greeting) \(person)")
}
return greetFn
}
let greet = getGreetFn(greeting: "Hi")
greet(person: "John")
上面的代码示例抛出以下错误:
error: extraneous argument label 'person:' in call
greet(person: "John")
^~~~~~~~~
根据我的理解,默认情况下需要参数标签。那么,为什么
person
函数的 greet
标签会导致错误?删除 person
标签可修复该错误。
Swift 版本:5.9.2
基本上,匿名函数(通常不准确地称为“闭包”)不能有外部标签是出于同样的原因:即,类型为函数的变量的类型不能有外部标签。你可以说
var myFunction: (String -> Void)?
但你不能说
var myFunction: (externalLabel: String -> Void)?
因此,尽管函数在 Swift 中是“一等公民”,但在传递它们的过程中幸存下来的是它们的 structural 签名,而不是它们的 verbal 签名。当您的代码运行时,我们知道的是
greet
是一个带有一个参数(字符串)的函数;该参数具有外部标签的规范丢失。
这有点不幸,因为外部标签可以帮助调用者理解参数的用途。但对此我们无能为力。这个问题几年前就已经被讨论过,结果证明不可能将外部标签的知识保留为函数类型的一部分。所以火车实际上已经离开车站了。