Wesley de Groot's Blog
Enums

Back

In this post, we'll explore enums in Swift, a powerful feature that allows you to define a group of related values. Enums are commonly used to represent a fixed set of options or states in your code, making it easier to work with and reason about different cases.

What are enums?

An enum in Swift is a data type that defines a group of related values. Each value in an enum is called a case, and you can define as many cases as needed to represent the different options or states of a particular type.

Here's an example of defining an enum in Swift:

enum CompassPoint {
    case north
    case south
    case east
    case west
}

In this example, we define an enum CompassPoint with four cases: north, south, east, and west. Each case represents a direction on a compass, and you can use these cases to work with compass directions in your code.

Using enums

Once you've defined an enum, you can use it to create instances of the enum type and work with the different cases. Here's an example of using the CompassPoint enum:

let direction: CompassPoint = .north

switch direction {
    case .north:
        print("Heading north")
    case .south:
        print("Heading south")
    case .east:
        print("Heading east")
    case .west:
        print("Heading west")
}

In this example, we create an instance of the CompassPoint enum called direction and set it to .north. We then use a switch statement to check the value of direction and print a message based on the case.

Enums are a powerful tool for representing a fixed set of options or states in your code. They help make your code more readable, maintainable, and robust by providing a clear and concise way to work with related values.

Associated Values

Enums in Swift can also have associated values, which allow you to attach additional data to each case. This is useful when you need to store extra information along with the case.

Here's an example of an enum with associated values:

enum PokemonState {
    case idle
    case walking(speed: Double)
    case running(speed: Double)
    case attacking(damage: Int)
    case catched(pokemon: String)
    case fainted
}

let dragonite: PokemonState = .attacking(damage: 10)
let trainer: PokemonState = .catched(pokemon: "Pikachu")
let lugia: PokemonState = .idle

switch dragonite {
    case .idle:
        print("Dragonite is idle")
    case .walking(let speed):
        print("Dragonite is walking at speed \(speed)")
    case .running(let speed):
        print("Dragonite is running at speed \(speed)")
    case .attacking(let damage):
        print("Dragonite is attacking with damage \(damage)")
    case .catched(let pokemon):
        print("Dragonite has catched \(pokemon)")
    case .fainted:
        print("Dragonite has fainted")
} // Output: Dragonite is attacking with damage 10

switch trainer {
    case .idle:
        print("Trainer is idle")
    case .walking(let speed):
        print("Trainer is walking at speed \(speed)")
    case .running(let speed):
        print("Trainer is running at speed \(speed)")
    case .attacking(let damage):
        print("Trainer is attacking with damage \(damage)")
    case .catched(let pokemon):
        print("Trainer has catched \(pokemon)")
    case .fainted:
        print("Trainer has fainted")
} // Output: Trainer has catched Pikachu

switch lugia {
    case .idle:
        print("Lugia is idle")
    case .walking(let speed):
        print("Lugia is walking at speed \(speed)")
    case .running(let speed):
        print("Lugia is running at speed \(speed)")
    case .attacking(let damage):
        print("Lugia is attacking with damage \(damage)")
    case .catched(let pokemon):
        print("Lugia has catched \(pokemon)")
    case .fainted:
        print("Lugia has fainted")
} // Output: Lugia is idle

In this example, we define an enum PokemonState with cases representing different states of a Pokemon. Each case has an associated value that provides additional information about the state. We then create instances of the enum with different cases and use a switch statement to handle each case.

Enums with associated values are a powerful feature of Swift that allows you to model complex data structures and represent different states in your code.

Raw Values

Enums in Swift can also have raw values, which are pre-defined values associated with each case. Raw values are useful when you need to map an enum case to a specific value, such as an integer or string.

Here's an example of an enum with raw values:

enum Pokemon: Int {
    case pikachu = 25
    case dragonite = 149
    case lugia = 249
}

let pikachuId = Pokemon.pikachu.rawValue
let dragoniteId = Pokemon.dragonite.rawValue
let lugiaId = Pokemon.lugia.rawValue

print("Pikachu Pokedex number: #\(pikachuId)")
print("Dragonite Pokedex number: #\(dragoniteId)")
print("Lugia Pokedex number: #\(lugiaId)")

In this example, we define an enum Pokemon with raw values of type Int. Each case is associated with a specific integer value, and we access the raw value of each case using the rawValue property.

Enums with raw values are a convenient way to map enum cases to specific values and provide a consistent way to work with related values in your code.

Use Cases

Enums are commonly used in Swift to represent a fixed set of options or states in your code. Here are some common use cases for enums:

  • Representing different states of an object or system
  • Defining a set of options for user input
  • Modeling different types of data or entities
  • Mapping enum cases to specific values or behaviors

By using enums in your code, you can make it more readable, maintainable, and robust by providing a clear and concise way to work with related values.

Caveats

Enums in Swift are powerful tools for modeling data and representing different states in your code. However, there are some limitations and considerations to keep in mind when working with enums:

  • Enums with associated values can become complex and hard to manage if they have too many cases or associated data.
  • Raw values in enums are limited to specific types, such as integers, strings, and floating-point numbers.
  • Enums with raw values must have unique raw values for each case to avoid conflicts.

When using enums in your code, consider the complexity of the data you're modeling and choose the appropriate enum type (plain, associated values, or raw values) based on your needs.

Conclusion

Enums are a fundamental part of Swift that provide a flexible and expressive way to define a group of related values. By understanding how to define enums, work with associated values and raw values, and use enums in your code, you can write cleaner, more maintainable, and more robust code that is easier to reason about and work with.

Resources:
https://docs.swift.org/swift-book/documentation/the-swift-programming-language/enumerations/

Read more

Share


Share Mastodon Twitter LinkedIn Facebook
x-twitter mastodon github linkedin discord threads instagram whatsapp bluesky square-rss sitemap