Closure-based type erasure

The final step in our closure-based type erasure is to implement the initializer that will be used to wrap Cows and Goats:

final class AnyAnimal<T>: Animal where T: Food {
typealias FoodType = T

private let eatBlock: (T) -> Void

init<A: Animal>(animal: A) where A.FoodType == T {
eatBlock = animal.eat
}

func eat(food: T) {
eatBlock(food)
}
}

Let's sum up the changes:

Let's now gather the flock of grass eaters and make let them graze freely in the fields:

let aCow = AnyAnimal(animal: Cow())
let aGoat = AnyAnimal(animal: Goat())

let grassEaters = [aCow, aGoat] // it's a small flock but a significant one
assert(grassEaters is [AnyAnimal<Grass>]) // Yay! All grass eaters

grassEaters.forEach { (animal) in // They are quire hungry let them eat
animal.eat(food: Grass())
}

// Output:
Grass is yummy! moooooo!
Grass is good! meehhhh!

This concludes the implementation of the closure based type erasure. Now, let's take a complete look at the box-based type erasure. While more verbose, this implementation should not scare you away.