Skip to content

Instantly share code, notes, and snippets.

@davidbalbert
Created September 21, 2022 02:52
Show Gist options
  • Save davidbalbert/d516df16394012f198c69ae20d387dfb to your computer and use it in GitHub Desktop.
Save davidbalbert/d516df16394012f198c69ae20d387dfb to your computer and use it in GitHub Desktop.
Three implementations of a type-erased Equatable
// 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