Hashable OptionSet in Swift
This post explains how to create an OptionSet in Swift that also implements the Hashable protocol. That way it can be used in a Dictionary, for example. Even though it’s super simple, I couldn’t find a documented example online so I thought I’d put one together.
Motivation
I’ve been recently working on a game using Apple’s SpriteKit and reached a point where I needed to implement and track in-game achievements. A user on reddit suggested using an OptionSet to store which achievements have been unlocked and a Dictionary as an “achievements encyclopedia” of sorts, which turned out to be a great suggestion! In order to make that work, the OptionSet also had to implement the Hashable protocol.
Why it made sense for my use case:
- OptionSets make bitwise operations relatively painless, so headaches are avoided there
- I’m not planning on a ton of achievements (the limit is the number of bits in an Int)
- Storing an integer (the OptionSet’s rawValue) in UserDefaults is really easy, and it’s storage efficient.
Hashable Protocol Requirements
- A hashValue integer is required as a way to uniquely profile (ideally) the contents of a hash
- An
==
function to compare hashes.
Final Code
This implementation uses the OptionSet’s rawValue as a unique indicator. Since hashValue defers to rawValue, it’s being used in the ==
function. This way we’re consolidating responsibility to hashValue. But alternatively you could:
return lhs.rawValue == rhs.rawValue