在 javascript 中,我们经常使用 IIFE。就像是
(function() {
...do stuff to avoid dirtying scope.
}());
Swift 中有闭包,函数是第一类对象。我的问题是:Swift 中是否有等效的 IIFE?
这里接受的答案是误导性的——有一种更简单、更优雅的方式来创建立即调用的闭包表达式 (IICE)。
有关语法的所有细节和差异,请参阅Apple Swift 文档以了解闭包。对于一个简单的演示,请参见:
let dateString: NSString = { date in
let timestampFormatter = NSDateFormatter()
timestampFormatter.dateStyle = .MediumStyle
timestampFormatter.timeStyle = .MediumStyle
return timestampFormatter.stringFromDate(date)
}(NSDate())
您可以使用闭包实现类似的效果,当然:
func iife( f : () -> () ) {
f()
}
然后说
iffe {
// my code here
}
如果你真正需要的只是一个作用域,而 Swift 不支持使用 {..} 作为“作用域运算符”,你总是可以这样做
if 1 == 1 {
// oh, look, a scope :-)
}
作为实现相同效果的不那么花哨的方式。如果您尝试使用 RAII 模式,则需要依靠 ARC 为您清理,或者使用闭包
if true {
// should also work instead of if 1 == 1
}
这是 Swift 立即调用闭包表达式 (IICE) 的另一个示例——我将其发音为“Icky”(向 JavaScript 的 IIFE 致敬,发音为“Iffy”——http: //benalman.com/news/2010/11 /立即调用函数表达式/)
var player:AVAudioPlayer = {
let path = Bundle.main.path(forResource: "sound1", ofType: "mp3")!
let url = NSURL(fileURLWithPath: path)
let p = try! AVAudioPlayer(contentsOf: url as URL)
p.volume = 0.3
p.prepareToPlay()
return p
}()
如果你使用lazy
修饰符,你就可以访问self
.
来自 Swift 语言指南:“当属性的初始值依赖于外部因素时,延迟属性很有用,这些因素的值在实例初始化完成后才知道。当属性的初始值需要复杂时,延迟属性也很有用或计算量大的设置,除非需要,否则不应执行。”
let startVolume:Float = 0.3
lazy var player:AVAudioPlayer = {
let path = Bundle.main.path(forResource: "sound1", ofType: "mp3")!
let url = NSURL(fileURLWithPath: path)
let p = try! AVAudioPlayer(contentsOf: url as URL)
p.volume = self.startVolume
p.prepareToPlay()
return p
}()
另请参阅 Swift 语言指南中的“使用闭包或函数设置默认属性值”。
当我想要一次性执行代码来初始化属性时,我发现了立即调用闭包的用途。例如:
class MyClass {
//One time initialization of managedObjectContext property
lazy var managedObjectContext: NSManagedObjectContext = { () -> NSManagedObjectContext in
let context = NSManagedObjectContext()
//do all the initial setup, etc...
return context
}()
//more stuff...
}
还有其他方法可以实现相同的目标,但我发现这是一个不错的模式。
您可以使用内置do {}
而无需catch
do {
// local scope
let x = 10
print(x)
}
// global scope
let x = "string"
print(x)
这个怎么样?
({
/* Code here */
}()) == ()
或这个?
({
print("hi")
}()).self
还是来自 JS?
({
print("hi")
}())