Swift中Closure块语法背后的逻辑推理是什么?

时间:2015-12-18 01:40:35

标签: swift

根据Apple documentation,Closure的语法如下

{ (parameters) -> return type in
    statements
}

将参数和返回类型放在curlies中的逻辑推理是什么,而不是使用更熟悉的函数类型语法,例如

 func name(parameters) -> return_type { 
        statements
    }

1 个答案:

答案 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开发人员来说,这很奇怪。但它对于封闭来说几乎没有效果。