Created
September 21, 2022 02:52
-
-
Save davidbalbert/d516df16394012f198c69ae20d387dfb to your computer and use it in GitHub Desktop.
Three implementations of a type-erased Equatable
This file contains hidden or 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
// Three implementations of a type-erased Equatable | |
struct AnyEquatable: Equatable { | |
class BoxBase { | |
func isEqual(_ other: BoxBase) -> Bool { | |
fatalError("not implemented") | |
} | |
} | |
class Box<E: Equatable>: BoxBase { | |
var wrapped: E | |
init(_ e: E) { | |
wrapped = e | |
} | |
override func isEqual(_ other: BoxBase) -> Bool { | |
if let other = other as? Box<E> { | |
return wrapped == other.wrapped | |
} else { | |
return false | |
} | |
} | |
} | |
private var box: BoxBase | |
init<E: Equatable>(_ e: E) { | |
box = Box(e) | |
} | |
static func == (_ lhs: AnyEquatable, _ rhs: AnyEquatable) -> Bool { | |
lhs.box.isEqual(rhs.box) | |
} | |
} | |
let x = AnyEquatable(5) | |
let y = AnyEquatable("asdf") | |
x == y | |
struct AnyEquatable1: Equatable { | |
var wrapped: Any | |
private var isEqual: (AnyEquatable1) -> Bool | |
init<E: Equatable>(_ e: E) { | |
wrapped = e | |
isEqual = { e == $0.wrapped as? E} | |
} | |
static func == (_ lhs: AnyEquatable1, _ rhs: AnyEquatable1) -> Bool { | |
lhs.isEqual(rhs) | |
} | |
} | |
let x1 = AnyEquatable1(5) | |
let y1 = AnyEquatable1("asdf") | |
x1 == y1 | |
// Swift 5.7. The good stuff. | |
func == <E: Equatable>(_ lhs: E, _ rhs: some Equatable) -> Bool { | |
if let rhs = rhs as? E { | |
return lhs == rhs | |
} else { | |
return false | |
} | |
} | |
5 == "asdf" | |
let x2: any Equatable = 5 | |
let y2: any Equatable = "asdf" | |
x2 == y2 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment