Swift: Enums

Swift Enums

An enum is a data type that has a finite set of possible values. In this post we discuss will the most important aspects of enums in Swift.

Hint: This post has been updated to Swift 3

Declaration

The declaration of an enum is very straightforward in Swift. You do it with the enum keyword:

enum TestEnum {
    case One
    case Two
    case Three
}

Alternatively, you can combine cases, which doesn’t make any difference at all at this basic setup:

enum TestEnum {
    case One, Two
    case Three
}

Now you can declare a variable of this type and assign one of the TestEnum‘s values:

var anEnum: TestEnum
anEnum = .Three

Raw Values

It possible for an enum to have associcated default values, in Swift called raw values. If an enum has raw values, they must be all of the same type and every possible value has to have a raw value. Let’s take a look at an example:

enum TestEnum: Int {
    case One = 1
    case Two = 2
    case Three = 3
}

In this example, the type for the raw values is integer. Then all values get a raw value assigned. If an enum has raw values, you can easily access them by the property rawValue:

enum TestEnum: Int {
    case One = 1
    case Two = 2
    case Three = 3
}

var anEnum: TestEnum
anEnum = .One

print("\(anEnum.rawValue)") //prints 1

Associated Values

It is also possible that at initialization time a value can be associated with the enum. For that, you need to declare what type each associated value is of:

enum TestEnum {
    case One(Int)
    case Two(Int)
    case Three(Int)
}

var anEnum: TestEnum
anEnum = .One(1)

To access the associated value, you need to make use of a switch:

switch anEnum {
case let .One(number):
    print("\(number)")
case let .Two(number):
    print("\(number)")
case let .Three(number):
    print("\(number)")
}

Unfortunately, it is not possible to access the associated value directly. But you can make it much more convent by using a function inside of the enum.

Properties and functions

One very interesting feature of enums is, that they can also implement functions and properties. So it is possible for example to declare a function that returns the associated value:

enum TestEnum {
    case One(Int)
    case Two(Int)
    case Three(Int)
    
    func associatedValue() -> String {
        switch self {
        case let .One(number):
            return("\(number)")
        case let .Two(number):
            return("\(number)")
        case let .Three(number):
            return("\(number)")
        }
    }
}

var anEnum: TestEnum

anEnum = .One(1)
print(anEnum.associatedValue()) //prints 1

Indirect Enums

Since Swift 2.0 there are so called indirect enums. In the Xcode release notes there’s the following explanation:

Enums and cases can be marked indirect, which causes the associated value for the enum to be stored indirectly, allowing for recursive data structures to be defined.

So now enums can be recursive, that means you can for example build a tree with enums. Let’s take a look at an example:

indirect enum Tree {
    case Empty
    case Node(value:Int,left:Tree,right:Tree)
}

For a enum to be indirect, we must use the keyword indirect in front of the enum.  Now let’s create a tree:

let tree1 = Tree.Node(value: 1, left: Tree.Empty, right: Tree.Empty)
let tree2 = Tree.Node(value: 2, left: Tree.Empty, right: Tree.Empty)
let tree3 = Tree.Node(value: 3, left: Tree.Empty, right: Tree.Empty)
let tree4 = Tree.Node(value: 4, left: tree1, right: tree2)
let tree5 = Tree.Node(value: 5, left: tree3, right: Tree.Empty)
let tree = Tree.Node(value: 6, left: tree4, right: tree5)

It looks like this:

Bildschirmfoto 2015-08-04 um 11.57.54Now we can create a function that goes recursively through the tree and adds up all numbers:

func evaluateTree(tree:Tree) -> Int {
    switch tree {
    case .Empty:
        return 0
    case .Node(let value, let left, let right):
        return value + evaluateTree(tree: left) + evaluateTree(tree: right)
    }
}

print("\(evaluateTree(tree: tree))")

The printed result is 21.

[thrive_text_block color=”blue” headline=”Conclusion”]Enums are a very important language feature in Swift. They have all the standard functionality you know from other programming languages. In addition, there are also some very useful advanced features like adding properties and functions, indirect enums and enums with associated values.[/thrive_text_block]

References

Swift Programming Series (iBook Store)
Image: @ Ivan Ryabokon / Shutterstock.com