Skip to content

Instantly share code, notes, and snippets.

@vittoriom
Last active August 29, 2015 14:14
Show Gist options
  • Save vittoriom/77de1cad4f84ba2b8cf2 to your computer and use it in GitHub Desktop.
Save vittoriom/77de1cad4f84ba2b8cf2 to your computer and use it in GitHub Desktop.
Talking protocols
// Playground - noun: a place where people can play
// Please see http://ashfurrow.com/blog/protocols-and-swift/ to know what this is all about
protocol FoodConsumer {
var calorieCount: Double { get set }
var hydrationLevel: Double { get set }
}
protocol Food {
//By having a simple generic function we don't have to cast the returned value when we call the method on the food
func beConsumedBy<T where T:FoodConsumer>(consumer: T, grams: Double) -> T
}
struct Cat: FoodConsumer {
var calorieCount: Double = 0
var hydrationLevel: Double = 0
}
struct Kibble: Food {
let caloriesPerGram: Double = 40
func beConsumedBy<T where T : FoodConsumer>(consumer: T, grams: Double) -> T {
var newConsumer = consumer
newConsumer.calorieCount += grams * caloriesPerGram
return newConsumer
}
}
struct FancyFeast: Food {
let caloriesPerGram: Double = 80
let milliLitresWaterPerGram: Double = 0.2
//Boring to type, but autocompletion does all the work anyway
func beConsumedBy<T where T : FoodConsumer>(consumer: T, grams: Double) -> T {
var newConsuner = consumer
newConsuner.calorieCount += grams * caloriesPerGram
newConsuner.hydrationLevel += grams * milliLitresWaterPerGram
return newConsuner
}
}
extension Cat {
//We can directly return Cat here
func eat(food: Food, grams: Double) -> Cat {
return food.beConsumedBy(self, grams: grams)
}
}
let catFood = Kibble()
let wetFood = FancyFeast()
var dave = Cat()
//And no need to cast anymore
dave = dave.eat(catFood, grams: 30)
dave = dave.eat(wetFood, grams: 20)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment