2014-10-20 70 views
0

我想用递归体在swift中编写函数文字 - 在这种情况下,它只是将所有值添加到列表中。我收到一个错误,“变量在它自己的初始值中使用”。有什么想法可能是错误的吗?另外我知道我在这里做的是一个简单的减少,它被构建到Array中,我只是将它用作我在其他地方看到的示例。快速匿名函数递归

let list: Slice = [1,2,3,4,5,6,7,8,9,10] 

var closure = { (memo: Int, list: Slice<Int>) -> Int in 
    if (list.count == 0) { 
     return memo 
    } else { 
     return closure(memo + list[0], list[1..<list.count]) 
    } 
} 

let value = closure(0,list) 

回答

4

试试这个:

let list: Slice = [1,2,3,4,5,6,7,8,9,10] 

var closure:((Int, Slice<Int>) -> Int)! 
closure = { (memo, list) in 
    if (list.count == 0) { 
     closure = nil // remove retain cycle 
     return memo 
    } else { 
     return closure(memo + list[0], list[1..<list.count]) 
    } 
} 

let value = closure(0, list) 

编辑:

看到这部影片:Advanced Swift at WWDC14。从大约41:00开始。它显示了这种方法的缺点,以及更好的解决方法。

+0

谢谢,看来关键是,封闭变量都将被声明,然后再进行分配。你知道这是一个错误还是一个功能? – Brandon 2014-10-20 18:03:44

+0

我认为这是一项功能。编译器只会拒绝“在它自己的初始值内使用的变量”,这就是我们如何避免它。用'!'类型声明变量将被初始化为'nil',这是“初始值”。然后,作为一个正常的关闭行为,可以从关闭内部看到修改的“关闭”值。 – rintaro 2014-10-20 18:09:31

+0

查看我的编辑答案 – rintaro 2014-10-20 18:49:54

0

我知道这是很老,但我发现另一种选择:

let list : ArraySlice<Int> = [1,2,3,4,5,6,7,8,9,10] 

let closure = { (Void) -> ((Int, ArraySlice<Int>) -> Int) in 
    func f(memo: Int, list: ArraySlice<Int>) -> Int { 
     if (list.count == 0) { 
     return memo 
     } else { 
     return f(memo + list[list.startIndex], list: list[(list.startIndex + 1)..<list.endIndex]) 
     } 
    } 
    return f 
}() 

let value = closure(0, list)