根据Apple documentation,Closure的语法如下
{ (parameters) -> return type in
statements
}
将参数和返回类型放在curlies中的逻辑推理是什么,而不是使用更熟悉的函数类型语法,例如
func name(parameters) -> return_type {
statements
}
答案 0 :(得分:3)
闭包语法是在某些常见情况下简化方式的方式。考虑命名函数语法,如果它用于闭包(显然删除name
,因为闭包是匿名函数文字)。
而不是当前的方法(以最详细的形式):
let f: (Type) -> ReturnType = { (parameter: Type) -> ReturnType in
return process(parameter)
}
它将是:
let f: (Type) -> ReturnType = func (parameter: Type) -> ReturnType {
return process(parameter)
}
这有很多问题。首先,闭包通常可以推断出它们的参数和返回类型,因此它的语法是:
let f: (Type) -> ReturnType = func (parameter) {
return process(parameter)
}
这开始变得有些混乱。这是一个返回Void的函数,还是一个返回ReturnType的函数?在标准的命名函数语法中,不使用返回类型意味着Void,但在这里它并不那么明显。编译器是肯定的;没有含糊之处,但它已经以微妙的方式偏离了命名函数语法。
(这本来是比较一致的,使所有功能,包括他们的返回类型,但是我想很多雨燕的开发者将被打破到必须键入-> Void
如此频繁。或者,他们可以有,所有功能都暗示返回类型,就像在Scala中一样,但他们认为这会损害可读性。)
现在考虑参数是隐式的并假设返回的情况:
let f: (Type) -> ReturnType = func { process($0)}
这是一个非常非常常见的案例。例如,考虑它对map
的作用:
xs.map(func { process($0) })
我认为这里的额外func
只是噪音。 xs.map{ process($0) }
是更好的IMO。
更深层次的问题是为什么函数不遵循闭包语法。如果没有"方法,那么实际上会有很多好处。只有功能属性,如:
struct Foo {
let dothing = { (x: Int) -> Int in x * 2 }
}
而不是
struct Foo {
func dothing(x: Int) -> Int { return x * 2 }
}
命名函数如此特殊的事实实际上是关于Swift的奇怪之处,它引入了许多令人头疼的问题(就像你不能使用函数属性来符合协议,只有命名函数)。
但是,提供func
语法对C,Java和JavaScript开发人员来说更为自然,这就是我怀疑它的原因。对于ML和Scala开发人员来说,这很奇怪。但它对于封闭来说几乎没有效果。