Полезным инструментом в наборе инструментов любого программиста является перечисление или перечисление. Они обеспечивают взаимодействие с безопасным типом и группировку связанных переменных. В этом посте будут обсуждаться перечисления, а также то, как Swift может их использовать. Будут рассмотрены основы перечисления, а также некоторые более сложные идеи, такие как связанные значения, необработанные значения и пользовательские инициализаторы.

Что такое перечисления?

Типы значений, называемые enums, используются для выражения коллекций связанных элементов. Они могут быть определены в Swift одним из двух способов: со связанными значениями или без них.

Перечисления без связанных значений

Перечисления без связанных значений проще в использовании, поскольку они не содержат никаких дополнительных данных для каждого сценария. Подумайте о следующем перечислении, которое изображает семь дней недели:

enum Day {
    case monday
    case tuesday
    case wednesday
    case thursday
    case friday
    case saturday
    case sunday
}

let currentday = Day.monday

Семь случаев enum дня в этом примере: понедельник, вторник, среда, четверг, пятница, суббота и воскресенье. День недели представлен каждым случаем.

Перечисления со связанными значениями

Перечисления со связанными значениями позволяют нам хранить дополнительные данные вместе с каждым случаем. Возьмите enum, представляющий измерения температуры, например:

enum Temperature {
  case celsius(Double)
  case fahrenheit(Double)
  case kelvin(Double)
}

let tempInCelsius = Temperature.celsius(27.0)
let tempInFahrenheit = Temperature.fahrenheit(83.0)
let tempInKelvin = Temperature.kelvin(373.0)

Температура перечисление на этом рисунке имеет три значения: градусы Цельсия, градусы Фаренгейта и кельвины. К каждому экземпляру прикреплено значение Double, которое соответствует показателю температуры на этой шкале.

Перечисления с необработанными значениями

Необработанные значения, которые связаны с каждым случаем, являются еще одним вариантом для перечислений. Любой тип значения, будь то Int, String или Double, может быть необработанным значением. Ниже приведен пример перечисления, содержащего необработанные значения:

enum Planet: Int {
    case mercury = 1
    case venus
    case earth
    case mars
    case jupiter
    case saturn
    case uranus
    case neptune
    case pluto
}

let earth = Planet(rawValue: 3)

Planet enum на этом рисунке имеет тип Int и включает девять случаев. В первых нескольких случаях необработанное значение определяется явно; для остальных случаев он выводится.

Перечисления с вычисляемыми атрибутами и методами

Так же, как классы и структуры, перечисления могут иметь вычисляемые свойства и методы. Для иллюстрации взгляните на обновленное Temperature enum ранее:

enum Temperature {
    case celsius(Double)
    case fahrenheit(Double)
    case kelvin(Double)

    var celsiusValue: Double {
        switch self {
        case .celsius(let value):
            return value
        case .fahrenheit(let value):
            return (value - 32) * (5/9)
        case .kelvin(let value):
            return value - 273.15
        }
    }

    func compare(to otherTemperature: Temperature) -> String {
        let selfCelsius = self.celsiusValue
        let otherCelsius = otherTemperature.celsiusValue
        
        if selfCelsius > otherCelsius {
            return "Higher"
        } else if selfCelsius < otherCelsius {
            return "Lower"
        } else {
            return "Equal"
        }
    }
}

let temp1 = Temperature.fahrenheit(83.0)
let temp2 = Temperature.celsius(27.0)

print(temp1.compare(to: temp2)) // --> "Higher"

В этом примере температура в градусах Цельсия возвращается вычисляемым свойством celsiusValue Temperature enum и строкой, указывающей, является ли одно значение температуры выше, ниже или равно другой возвращается методом compare(to:), который сравнивает два значения температуры.

Перечисления с пользовательскими инициализаторами

Точно так же, как классы и структуры, перечисления также могут иметь собственные инициализаторы. Это может быть полезно для предложения многих методов инициализации значения перечисления. Для иллюстрации взгляните на обновленное Temperature enum ранее:

enum Temperature {
    case celsius(Double)
    case fahrenheit(Double)
    case kelvin(Double)

    init(value: Double, scale: String) {
        switch scale.lowercased() {
        case "celsius":
            self = .celsius(value)
        case "fahrenheit":
            self = .fahrenheit(value)
        case "kelvin":
            self = .kelvin(value)
        default:
            self = .celsius(value)
        }
    }
}

let temp1 = Temperature(value: 77.0, scale: "Fahrenheit")
let temp2 = Temperature(value: 25.0, scale: "Celsius")

В этом примере используется пользовательский инициализатор для Temperature enum, который создает новое значение температуры на основе шкалы и получает значение и шкалу (в виде строки). Температура инициализируется как градусы Цельсия, если шкала не распознана.

Перечислить случаи как параметры функции

Как и любое другое значение, случаи enum можно использовать в качестве параметров функции. Рассмотрим приведенную ниже функцию, которая принимает случай Day enum в качестве параметра:

func getActivities(for day: Day) -> [String] {
    switch day {
    case .monday:
        return ["go to soccer"]
    case .tuesday:
        return ["go to library"]
    case .wednesday:
        return ["visit friends"]
    case .thursday:
        return ["go to arts class"]
    case .friday:
        return ["go to shop"]
    case .saturday:
        return ["tidy up room"]
    case .sunday:
        return ["go to baseball match"]
    }
}

let dayActivities = getActivities(for: .wednesday)
print(dayActivities) // prints "visit friends"

Функция getActivities(for:) в этом примере принимает случай Day enum в качестве аргумента и выводит массив действий в зависимости от дня.

Перебор случаев enum

Атрибут allCases в enum позволяет нам многократно перебирать все его варианты. Возьмем, к примеру, код, который выполняет итерацию по всем случаям Day enum:

for day in Day.allCases {
    print(day)
}

// prints:
// monday
// tuesday
// wednesday
// thursday
// friday
// saturday
// sunday

Это может быть полезно для создания списка всех вариантов, которые может иметь enum.

Заключение

Для организации связанных данных и взаимодействия с ними безопасным способом перечисления являются полезным инструментом. Их можно использовать как параметры функции и повторять. Они также могут содержать связанные значения, необработанные значения, вычисляемые свойства и методы и пользовательские инициализаторы. В этом посте мы рассмотрели как основы перечислений, так и некоторые более сложные идеи. Надеюсь, теперь вы знаете больше о том, как использовать enums в своих проектах Swift.

Повышение уровня кодирования

Спасибо, что являетесь частью нашего сообщества! Перед тем, как ты уйдешь:

  • 👏 Хлопайте за историю и подписывайтесь на автора 👉
  • 📰 Смотрите больше контента в публикации Level Up Coding
  • 🔔 Подписывайтесь на нас: Twitter | ЛинкедИн | "Новостная рассылка"

🚀👉 Присоединяйтесь к коллективу талантов Level Up и найдите прекрасную работу