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
Using the OptionSet in a Dictionary