Forked from brentsimmons/protocolequatable.swift
Last active
August 29, 2015 14:26
-
-
Save thanegill/c2cb6e3745342b6e2ab3 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//: 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