要实现递归函数的memoized版本,可以将该函数声明为非变异函数(根据WWDC 2014 - Advanced Swift)。例如,以下是Fibonacci函数的实现:
let fibonacci = memoize { (fibonacci: Int->Double, n: Int) in
n < 2 ? Double(n) : fibonacci(n-1) + fibonacci(n-2)
}
任何人都可以解释Swift中发生的事情吗?例如,Swift如何知道fibonacci在上面的代码片段中只接受一个参数?编译器如何解决这个问题?我们凡人如何解决这个问题?语法表达式在编译器语法(Normal Form / CFG)中的含义是什么?
答案 0 :(得分:2)
memoize
函数(来自that WWDC talk)的签名是:
func memoize<T: Hashable, U>( body: ((T)->U, T)->U ) -> (T)->U
如您所见,它接收一个正文函数((T)->U, T) -> U
,并返回另一个函数(T) -> U
。您可以将此功能用于您选择的任何类型,而不是T
和U
,T
必须为Hashable。
由于此处的body函数(您的trailing closure)已明确声明为((Int)->Double, Int)
,因此编译器可以通过complicated constraint-solving推断出T == Int
和U == Double
},所以memoize
返回的函数必然是(Int)->Double
。