Yesterday in #swift-lang, an enumeration discussion buzzed. A chat participant asked, “Is there any way to go backwards in an enum? I want to look up an enum based on a value.” The answer is simple and accessible. Creating enumerations from values returned by services and function represents an important touchpoint in Swift development.
RawRepresentable
The RawRepresentable protocol consists of two underlying functions: toRaw() and fromRaw(). These enable you to transform enumerations to and from underlying data states.
protocol RawRepresentable { typealias Raw class func fromRaw(raw: Raw) -> Self? func toRaw() -> Raw }
For example, if you base your enumeration on integers, you can use the underlying sequence to move to and from that representation.
enum Nums : Int { case Zero case One case Two case Three } var z : Nums = Nums.fromRaw(2)! z == .Two // true z == .Three // false
This example uses an Int raw-value type for its underlying representation. The type appears just after the name of the enumeration.
Fun with Raw Values
The enumeration values do not have to exactly match 0, 1, 2, etc. For example, you might assign arbitrary values to the enumeration entries.
enum Nums : Int { case Zero = 5 case One = 30 case Two = 15 case Three = 20 } var z : Nums = Nums.fromRaw(20)! z == .Two // false z == .Three // true println(Nums.Three.toRaw()) // prints 20
Nor are your raw-convertible enumerations limited to integers. You have access to any equatable literal, specifically integer literals, floating-point literals, string literals, booleans, and nil. For example, you might use strings as raw values:
enum Lets : String { case X = "x" case Y = "y" case Z = "z" } var zz = Lets.fromRaw("z") zz! == .Z // true println(Lets.Y.toRaw())
Each case must declare a unique name and value. If you skip the value for integers, as in the first example in this post, they implicitly inherit their order. The count starts at zero and increases monotonically from there.
Raw vs Associated Values
Don’t confuse raw values with associated values. A raw value is constant across all uses of an enumeration. They are defined in the enumeration declaration at compile time. Associated values enable you to store typed information in an enumeration. These are defined at runtime.
enum CocoaResult { case success(NSObject) // associated success value case failure(NSError) // associated error value }
2 Comments
var z : Nums = Nums.fromRaw(20)!
has been changed to
var z : Nums = Nums(rawValue: 20)!
as of: Xcode V 6.1 (6A1052d)
Nice article and thank you DB Warner for that handy tip