Руководство Swift Enum

1- Что такое Swift Enum?

В  Swift, используется ключевое слово  enum чтобы определить набор перечисленных элементов, вы не можете добавить или убрать количество элементов. Например, вы можете определить набор дней в неделе (Понедельник, вторник, ..., Воскресение)
Если не имеется  enum, чтобы создать набор дней недели, вы можете определить 7 чисел, представляющие дни недели.
WeekDayConstants.swift
import Foundation



// Defines the constants are the days of the week.


let CONST_MONDAY = 2;
let CONST_TUESDAY = 3;
let CONST_WEDNESDAY = 4;
let CONST_THURSDAY = 5;

let CONST_FRIDAY = 6;
let CONST_ATURDAY = 7;
let CONST_SUNDAY = 1;
Модельная функция возвращает назврание работы соответствующей определенному дню недели. (Похоже на расписание)
GetJobByDay.swift
import Foundation


// Returns name of Job will do

func getJobByDay(dayInWeek: Int) -> String {
   
    if (dayInWeek == CONST_SATURDAY
        || dayInWeek == CONST_SUNDAY) {
        return "Nothing";
    }
    return "Coding";
   
}
Можно увидеть, что код выше не безопасен. Например, когда вы определяете значение дней недели и они случайно совпадают. Или вызываете функцию  getJobByDay(Int) но входной параметр еще не входит в предопределенные значения. 
  1. No Type-Safety: Для начала это не безопасный вид, вы можете вызвать метод getJobByDay(Int) и передать любые значения Int.
  2. No Meaningful Printing: Если вы хотите распечатать дни недели, распечатается число вместо слова "Понедельник". 
И это способ создания  enum, специальный набор.
WeekDay.swift
import Foundation

// Define an Enumeration.
enum WeekDay
{
    // Elements
    case MONDAY
    case TUESDAY
    case WEDNESDAY
    case THURSDAY
    case FRIDAY
    case SATURDAY
    case SUNDAY
    
}
Например, используя  Enum:
WeekDayTest.swift
import Foundation


// Returns name of Job will do
func getJob(weekDay: WeekDay) -> String  {
   
    if (weekDay == WeekDay.SATURDAY || weekDay == WeekDay.SUNDAY) {
       
        return "Nothing"
       
    }
    return "Coding"
   
}

func test_getJob()   {
   
    var weekDay = WeekDay.TUESDAY
   
    print("Day = \(weekDay)")
   
    var job = getJob(weekDay)
   
    print("Job = \(job)")
   
}
 

2- Получить все элементы Enum

Нет определенной функции или метода, который позволит вам получить список элементов любого  Enum, но вы можете сами дать определение переменной, которая включает все элементы  Enum.
Данный пример определяет Enum, в  Enum так же определяется константа содержащая все его элементы. 
Season.swift
import Foundation

// The seasons
enum Season  {
   
    case Spring
   
    case Summer
   
    case Autumn
   
    case Winter
   
   
    // Static Constant, contains all the elements of the Enum.
    static let allValues = [Spring, Summer, Autumn, Winter]
   
   
}
 
GetAllSeasons.swift
import Foundation



func test_getAllSeasons()   {
 
 
   for season in Season.allValues  {
       print(season)
   }
 
}
Результаты запуска примера:

3- Enum в команде switch

Похоже на примитивные виды данных ( Int, Float,..) Enum может использоваься как параметр в команде  switch.
Посмотрим на пример:
SwitchDemo.swift
import Foundation


func test_switchEnum() {
   
    var day = WeekDay.THURSDAY;
   
    switch (day) {
       
    case .MONDAY:
       
        print("Working day");
       
    case .SATURDAY, .SUNDAY :
       
        print("Holiday");
       
    default:
        print(day);
       
    }
   
}
 
Изменить код  main.swift:
main.swift
import Foundation

test_switchEnum()
Запуск примера:

4- Enum с необработанными значениями (raw value)

Вы можете определить  Enum с необработанными значениями (raw values), необработанные значения могуть быть вида  String, character, Int, Number,... Такой  Enum расширяет один из видов String, Character, Int,..

Например, вы можете определить  Enum является набором месяцев в году, данный набор будет содержать необработанные значения от 1 до 12.
RawValueEnum.swift
import Foundation

// Define an Enum is enumeration of months in year.
// It extends from Int
enum Month : Int  {
    
    // Assign the value (raw value) for the element.
    // (If the element is not assigned the value,
    // Default its value equal to the value of the previous element plus 1).
    case January = 1,
    
    February, March, April, May, June,
    
    July, August, September, October, November, December
    
    // Static Constant contains all the values of Month enum.
    static let allValues = [January,February, March,
                            April, May, June, July, August,
                            September, October, November, December]
    
}

//

enum Suit:String {
    
    case Spades = "♠"
    
    case Hearts = "♥"
    
    case Diamonds = "♦"
    
    case Clubs = "♣"
    
    // Static Constant contains all the values of Suit enum.
    static let allValues = [Spades,Hearts,Diamonds,Clubs]
    
}
Распечатать элементы enum Month, и соответсвующие необработанные данные ( raw value).
RawValueEnumTest.swift
import Foundation


func test_MonthEnum()   {
    
    // Print out all elements and raw values of enum.
    
    print("All element/raw value of Month enum");
    
    for e in Month.allValues  {
        
        let rawValue = e.rawValue
        
        print("Element \(e), raw value: \(rawValue)"  );
    }

    print("---------------------");
    
    // Print out all elements and raw values of enum.
    
    print("All element/raw value of Suit enum");
    
    for e in Suit.allValues  {
        
        let rawValue = e.rawValue
        
        print("Element \(e), raw value: \(rawValue)"  );
    }
    
}
Запуск примера:

5- Enum с ассоциированными значениями

Вы можете создать  Enum с элементам содержащими значения ассоциированными с ним.
Я предположу ситуацию, вы создаете Enum содержаций виды рекламы.
  1. GIFT: Подарок
  2. DISCOUNT: Скидка
  3. MONEY: Денежный подарок
  4. SHIPPING: Бесплатная доставка.
Проблема в том, что в каждом виде рекламы, имеется связанные с ней значения, например подарок ( GIFT) что подарить, какое количество. Или денежный подарок ( MONEY) то какую сумму денег подарить,...

И так каждый элемент  Enum имеет разные параметры. Посмотрим пример: 
Promotion.swift
import Foundation

// Promotion types
enum Promotion   {
    
    //
    case GIFT (name: String, quantity: Int)
    
    // Discount (percel: 0 - 100)
    case DISCOUNT(percent: Int)
    
    //
    case MONEY(amount : Int)
    
    // Free shipping
    case SHIPPING
    
}
Enum Promotion имеет только 4 параметра, вы не можете добавить или убрать эти элементы, они имеют связанные значения с элементами определяющими время запуска рекламы. 
PromotionTest.swift
import Foundation

// Simulate a purchase, and get promotions.
func getRandomPromotion() -> Promotion {
    
    // A random value
    var random: UInt32 = arc4random()
    
    // Divided by 4 and returns the remainder (0, 1, 2, 3).
    random = random % 4
    
    switch random  {
        
    case 0:
        return Promotion.DISCOUNT(percent: 10)
    case 1:
        return Promotion.GIFT(name: "Doll", quantity: 1)
    case 2:
        return Promotion.MONEY(amount: 100)
    case 3:
        return Promotion.SHIPPING
    default:
        return Promotion.SHIPPING
    }
    
}


func test_Promotion()   {
   
    
    var myProm = getRandomPromotion()
    
    print("Get Promotion: \(myProm)")
    
    
    switch myProm {
    case .DISCOUNT(let percent):
        print("Percent is: \(percent)")
    case .GIFT(let name, let quantity ):
        print("Gift name: \(name), quantity: \(quantity)")
    case .MONEY(let amount) :
        print("Amount: \(amount)")
    default:
        print(myProm)
    }
}
 
Изменить  main.swift:
main.swift
import Foundation

test_Promotion()
Запуск примера:

6- Методы в Enum

Вы можете определить методы в  Enum, смотрите пример:
Currency.swift
import Foundation


// Currencies
enum Currency   {

    case USD
    case YEN
    case VND
    
    
    
    func description() -> String  {
        
        switch self {
        case USD:
            return "America's currency"
        case YEN:
            return "Japan's currency"
        case VND :
            return "Vietnam's currency"
        }
    }
    
}