[Swift]: enumeration
swift
05/17/2019
Enumeration in Swift
enumeration example
SWIFT
enum WaterBrand {    case aquafina    case dasani    case evian    case fiji}- enum is a data type that can have only discrete values; it can't be anything else
- enum is a value type like struct. i.e. it gets copied as it is passed around
enum in Swift
enum in Swift can have associated data
SWIFT
enum WaterBrand {    case aquafina(bundle: Int)    case dasani(size: BottleSize)    case evian(String, ounces: Int)    case fiji}- evian(String, ounces: Int): Doesn't have to have a variable name as it'll be called with a name
- BottleSize can be another enum:
SWIFT
enum BottleSize {    case small    case large}Setting a value of enum
SWIFT
let brand = WaterBrand.aquiafina(bundle: 6)var other: WaterBrand = .fijiChecking enum's state
Check a state of enum can be done with switch and use let to access its associated data
SWIFT
// Ways to decalre variablesvar brand = WaterBrand.aquafina(bundle: 6)var evian = WaterBrand.evian("original", ounces: 32)var otherBrand = WaterBrand.dasani(size: .small)
// Prints "aqua" on consoleswitch brand {    case .aquafina:        print("aqua")    case .dasani:        print("dasani")    // Accessing associated data; you can change assigned name of var    case .evian(let whatever, let oz):        print("\(oz)oz \(whatever) evian")    case .fiji:        break    default:        print("other")}- switch brand{} thus it will print "aqua" on console
- If it were to be switch evian{} it will print "32oz original evian"
Methods/Property(computed) in enum
SWIFT
enum WaterBrand {    ...
    // func in enum    func isLargeBundle(bundles: Int) -> Bool {        return bundles > 24    }
    // computed property in enum    var price: Int {        // Code for computed property    }}- enum can have function and computed property like class/struct
- Can't have var that is stored property. Store property should be done in case with associated data
Getting own associated data in func in enum
Use self to get its own associated data in func
SWIFT
enum WaterBrand {    ...
    func isLargeBundle(bundles: Int) -> Bool {        swift self {            case .aquafina(let bundleAqua):                return bundleAqua > bundles            case .dasani, fiji:                // Ex) Dasani, Fiji are always a large bundle                return true            case .evian(_, let oz):                return oz > 32        }    }}Modifying enum
It's possible to reassign self inside enum method. This requires mutating since enum is a value type
SWIFT
enum WaterBrand {    ...    mutating func switchToFiji() {        self = .fiji    }}Optional is an enum
Optional is is special; has special syntax that other types don't have.
Here's a conceptual structure:
SWIFT
enum Optional<T> { // generic type, like Array<Element> or Dictionary<Key,Value>    case none    case some(<T>) // Some case has associated data of type T}Declaring optional & assigning values
SWIFT
var hello: String?             // var hello: Optional<String> = .nonevar hello: String? = "hello"   // var hello: Optional<String> = .some("hello")var hello: String? = nil.      // var hello: Optional<String> = .noneUnwrapping
SWIFT
let hello: String? =...print(hello!)// Aboe code would look like..switch hello {    case.none: // crash    case.some(let data): print(data)}SWIFT
if let greeitng = hello {    print(greeting)} else {
}////////////////////switch hello {    case.some(let data): print(data)    case.none: { //else }}Implicitly unwrapped optional
SWIFT
var hello: String!hello = ...print(hello)////////////////////var hello: Optional<String> = .noneswitch hello {    case .none: // crach    case .some(let data): print(data)}Nil-coalescing operator (Optional defaulting)
SWIFT
let x: String? = ...let y: x ?? "foo"////////////////////switch x {    case .none: y = "foo"    case .some(let data): y = data}Optional chaining
SWIFT
let x: String? = ...let y = x?.foo()?.bar?.z////////////////////switch x {   case .none: y = nil   case .some(let data1):       switch data1.foo() {           case .none: y = nil           case .some(let data2):               switch data2.bar {                   case.none: y = nil                   case .some(let data3): y = data3.z               }       }}