Skip to content

Instantly share code, notes, and snippets.

@Iron-Ham
Last active March 22, 2023 14:30
Show Gist options
  • Save Iron-Ham/d0eb72822f0965a3688241a70ec08f8c to your computer and use it in GitHub Desktop.
Save Iron-Ham/d0eb72822f0965a3688241a70ec08f8c to your computer and use it in GitHub Desktop.
Use property wrappers to ignore a variable for synthesized `Equatable` and `Hashable`.
import Foundation
@propertyWrapper
struct IgnoreEquatable<Wrapped>: Equatable {
var wrappedValue: Wrapped
static func == (lhs: IgnoreEquatable<Wrapped>, rhs: IgnoreEquatable<Wrapped>) -> Bool {
true
}
}
@propertyWrapper
struct IgnoreHashable<Wrapped>: Hashable {
@IgnoreEquatable var wrappedValue: Wrapped
func hash(into hasher: inout Hasher) {}
}
// Usage
// You can use this to ignore variables and allow for synthesized `Hashable` and `Equatable` declarations.
// Example:
// Before
struct SomeStruct: Equatable, Hashable {
let count: Int
let action: () -> Void
static func == (lhs: SomeStruct, rhs: SomeStruct) -> Bool {
return lhs.count == rhs.count // doesn't update automatically as we change and update the struct
}
func hash(into hasher: inout Hasher) {
hasher.combine(count)
}
}
// After
// This equality and hashable declaration is generated, and so will update as the struct changes.
struct SomeStruct2: Equatable, Hashable {
let count: Int
@IgnoreHashable var action: () -> Void
}
@Iron-Ham
Copy link
Author

Iron-Ham commented Sep 2, 2021

Note that Hashable requires Equatable, so in order to ignore a variable for both Equatable and Hashable, all you need is the @NotHashable property wrapper. ❤️

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment