Skip to content

Instantly share code, notes, and snippets.

@glessard
Last active August 29, 2015 14:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save glessard/0ad867b399df4b538dba to your computer and use it in GitHub Desktop.
Save glessard/0ad867b399df4b538dba to your computer and use it in GitHub Desktop.
A defer keyword in Swift
//
// 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()
@glessard
Copy link
Author

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment