Last active
August 29, 2015 14:05
-
-
Save glessard/0ad867b399df4b538dba to your computer and use it in GitHub Desktop.
A defer keyword in Swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// defer.swift | |
// DeferredTaskList | |
// | |
private class DeferredTasks | |
{ | |
private typealias Task = () -> () | |
var list = [Task]() | |
deinit | |
{ | |
for task in list.reverse() | |
{ | |
task() | |
} | |
} | |
} | |
struct Deferred | |
{ | |
private var d = DeferredTasks() | |
init() { } | |
init(_ task: () -> ()) | |
{ | |
d.list.append(task) | |
} | |
init<IgnoredType>(task: () -> IgnoredType) | |
{ | |
d.list.append { _ = task() } | |
} | |
func defer(task: () -> ()) | |
{ | |
d.list.append(task) | |
} | |
func defer<IgnoredType>(task: () -> IgnoredType) | |
{ | |
d.list.append { _ = task() } | |
} | |
} | |
private func test() | |
{ | |
var T = Deferred {println("last thing to happen.")} | |
var f1 = "fileref 1" | |
T.defer {println("close " + f1)} | |
println(f1 + " is ready for use") | |
var f2 = "fileref 2" | |
T.defer {println("close " + f2)} | |
println(f2 + " is ready for use") | |
println("do things with " + f1 + " and " + f2) | |
} | |
test() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
A simple way to do in swift something similar to go's defer statement.
Difference: it's a closure being passed, so context is carried. Go's defer is somewhat like a pause between function parameter evaluation and function execution.
The trick is to use the deinitializer to trigger the execution of a list of closures.
The output of test() is as follows:
fileref 1 is ready for use
fileref 2 is ready for use
do things with fileref 1 and fileref 2
close fileref 2
close fileref 1
last thing to happen.