在Swift中保持关闭内的局部状态
有没有办法在闭包中声明一个变量,并让它在枚举调用之间保持其状态。具体来说,我想在一个数组上编写一个.filter闭包,该数组返回一个没有重复的数组版本。像这样的在Swift中保持关闭内的局部状态,swift,closures,Swift,Closures,有没有办法在闭包中声明一个变量,并让它在枚举调用之间保持其状态。具体来说,我想在一个数组上编写一个.filter闭包,该数组返回一个没有重复的数组版本。像这样的 let withDupes = ["C", "D", "A", "J", "J", "D", "M", "Z", "A"] let noDupes = withDupes.filter { static var seenLetters: [Character] = [ ] //would like to use st
let withDupes = ["C", "D", "A", "J", "J", "D", "M", "Z", "A"]
let noDupes = withDupes.filter {
static var seenLetters: [Character] = [ ] //would like to use static like in C
if !contains(seenLetters, $0) {
seenLetters.append($0)
return true
}
else {
return false
}
}
//理想情况下,noDupes现在应该是[“C”、“D”、“A”、“J”、“M”、“Z”]
当我尝试以这种方式使用static时,Swift会报告一个错误。如果我全局声明seenLetters,.filter可以正常工作。是否有我丢失或误用的语言功能?正如您所发现的,Swift不允许您直接在函数或闭包中定义
静态变量。然而,还有另一种方法可以完成你想做的事情。如果将重复数据消除代码移到其自己的函数中,则可以创建一个作用域为该函数的seenLetters
数组
,并在过滤器
调用中使用该数组。像这样:
let withDupes = ["C", "D", "A", "J", "J", "D", "M", "Z", "A"]
func deduplicate(arr: [String]) -> [String] {
var seenLetters = [String]()
return arr.filter {
if !contains(seenLetters, $0) {
seenLetters.append($0)
return true
}
else {
return false
}
}
}
let noDupes = deduplicate(withDupes)
请注意,由于您可以在其他函数中嵌入函数,因此这很好:
func someFunction() {
let withDupes = ["C", "D", "A", "J", "J", "D", "M", "Z", "A"]
func deduplicate(arr: [String]) -> [String] {
/* ... */
}
let noDupes = deduplicate(withDupes)
}
如果出于某种原因不想创建一个单独的函数来实现这一点,那么实际上也可以使用闭包来实现。诀窍是将闭包封装在另一个闭包中,该闭包定义一个局部seenLetters
变量并返回原始闭包。这样,seenLetters
的作用域就是外部闭包,您的内部闭包可以按照您的意愿使用它
let noDupes = withDupes.filter({
var seenLetters = [String]()
return {
if !contains(seenLetters, $0) {
seenLetters.append($0)
return true
}
else {
return false
}
}
}()) // Immediately calling the outer closure so that the inner one is returned to filter
有几件事需要注意。。。首先,您需要将外部闭包的返回值传递给filter
函数,只需立即调用它即可。第二,您不能将其用作尾随闭包,因此必须在过滤器调用中将其包装在()
s中。第三,这与使用嵌入式函数基本相同,只是形式更紧凑