#19: Protocol Extensions

Protocol Extensions are a new feature of Swift 2. They allow you to add new functions (complete with implementations) to any class that implements a protocol. The functionality is best explained with a simple example. Let’s say you wanted to add a way to shuffle arrays.

In Swift 1.2 and earlier, you’d probably add a shuffle function using something like this:


extension Array {
  mutating func shuffle() {
    for i in 0..<(count - 1) {
      let j = Int(arc4random_uniform(UInt32(count - i))) + i
      swap(&self[i], &self[j])
    }
  }
}

Which works great, but only applies to Array types. In Swift 2, you can add it to all mutable collections using Protocol Extensions.


extension MutableCollectionType where Self.Index == Int {
  mutating func shuffleInPlace() {
    let c = self.count
    for i in 0..<(c - 1) {
      let j = Int(arc4random_uniform(UInt32(c - i))) + i
      swap(&self[i], &self[j])
    }
  }
}

As you can see here, we’re also able to use Swift’s fantastic pattern-matching support to limit our extension to only mutable collections that use an Int as their index.