Skip to content

Instantly share code, notes, and snippets.

@thanegill
Forked from brentsimmons/protocolequatable.swift
Last active August 29, 2015 14:26
Show Gist options
  • Save thanegill/c2cb6e3745342b6e2ab3 to your computer and use it in GitHub Desktop.
Save thanegill/c2cb6e3745342b6e2ab3 to your computer and use it in GitHub Desktop.
//: Playground - noun: a place where people can play
// Got most of it from:
// https://developer.apple.com/sample-code/wwdc/2015/downloads/Crustacean.zip
// This is in the Protocol-Oriented Programming in Swift talk
// Pay special attention to the Heterogeneous Equality section, on page 2.
//
// Most comments directly copy/pasted from Crustacean Playground
protocol Account {
var accountID: String { get }
func isEqualTo(other: Account) -> Bool
}
struct FooAccount: Account {
var accountID = "foo"
}
struct BarAccount: Account {
var accountID = "bar"
}
// Value types should always be Equatable. Mostly this is just rote comparison
// of the corresponding sub-parts of the left-and right-hand arguments, but
// things get interesting below where handle heterogeneous comparison.
extension FooAccount: Equatable {}
func == (lhs: FooAccount, rhs: FooAccount) -> Bool {
return lhs.accountID == rhs.accountID
}
extension BarAccount: Equatable {}
func == (lhs: BarAccount, rhs: BarAccount) -> Bool {
return lhs.accountID == rhs.accountID
}
// Asking every Account to support a heterogeneous binary operation imposes
// quite a burden—one that is usually solved by adding a Self requirement to the
// protocol. However, equality is a special case, because there's usually a
// meaningful result when the types don't match: the instances can be assumed to
// be not-equal. We extend Equatable (which supports homogeneous equality
// comparison) to provide an isEqualTo for Account that returns false when the
// types don't match.
extension Account where Self: Equatable {
func isEqualTo(other: Account) -> Bool{
guard let o = other as? Self else { return false }
return self == o
}
}
// Use isEqualTo() to implement Equatable conformance to Account
func == (lhs: Account, rhs: Account) -> Bool {
return lhs.isEqualTo(rhs)
}
let foo = FooAccount()
let bar = BarAccount()
print(foo == bar) // False
var accounts: [Account] = [Account]()
accounts.append(foo)
accounts.append(bar)
print(accounts)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment