Closures: blocks you can pass around like a football

Syntax:

let greeting: () -> () {
    println("Hello World!")
}

Closures are an integral component of programming in Swift. They are literal functions, and as such, you can pass a closure or a named function as a closure value. They are also ARC objects and follow the same memory management rules as classes.

Trailing closure example

func repeat(count: Int, task: () -> ()) {
  for i in 0..<count {
    task()
  }
}
repeat(2) {
  println("Aloha!")
}
        

Sorting closure example


Swift Arrays only have one basic sort method which accepts a closure, so you can sort however you like. Technically there are two: sort, and sorted. The difference being "sorted" returns a new array, while "sort" rearranges the original array, and thus can only be used on arrays defined as variable. To use either of them, simply provide the signature, the "in" keyword, then the body of the function.
var users = ["Eve","Alice","Fred","Bob"]
var orderedArray = sorted(users, {(a: String, b: String) -> Bool in
  return a < b
})
        

However, due to Type Inference, this can be reduced to:

orderedArray = sorted(users, {a, b in
  return a < b
})


And through the magic of Implicit Arguments and Implicit Return, it can be reduced even further to:

orderedArray = sorted(users,{ $0 < $1 })

And if you want truly compact, but potentially hard to understand code, you can simplify it even more:

orderedArray = sorted(users, <)


Nested closure example


Closures can also be nested, and they can access local variables automatically. In the example below, an array of Int is passed to the "sum" function. The map method takes a closure which will be applied to all elements in the array. The map method then returns an array consisting of the mapped values. Here, that array isn't used, as we just want to iterate through the Ints and add them to "total". The "total" value is then returned by the "sum" function.
func sum(numbers: Int[]) {
  var total = 0
  numbers.map {
    total += $0
  }
  return total
}
        

Memory management example

By assigning a nested closure to a variable, you can keep the local function alive so that the state of the variables is maintained. In Version 1, the closure is directly assigned to a variable that exists outside the scope of the function. In Version 2, a second function is declared inside the first, and then that function is assigned to the outer variable. The end result is the same, but the former is cleaner code.
// Version 1
var onSpeedUpdate: (Int) -> Void = {}
func logSpeedChange(original: Int) {
  var old = original
  onSpeedUpdate = { current in
    println("Changed \(current - old)")
    old = current
  }
}

// Version 2
var onSpeedUpdate: (Int) -> Void = {}
func logSpeedChange(original: Int) {
  var old = original
  func log(current: Int) {
    println("Changed \(current - old)")
    old = current
  }
}
onSpeedUpdate = log