Enum
enum FastFoodMenu { case hamburger case fries case drink case cookie }
enum is value types (like struct)
associated data
enum FastFoodMenu { case hamburger(numberOfPatties: Int) case fries(size: FryOrderSize) case drink(String, ounces: Int) case cookie } enum FryOrderSize { case large case small }
setting enum value
let menuItem: FastFoodMenu = FastFoodMenu.hamburger(patties: 2) let otherItem: FastFoodMenu = FastFoodMenu.cookie or let otherItem: FastFoodMenu = .cookie
use switch
var menuItem: FastFoodMenu = FastFoodMenu.hamburger(patties: 2) switch menuItem { case FastFoodMenu.hamburger: print("burger") case FastFoodMenu.fries: print("fries") case FastFoodMenu.drink: print("drink") case FastFoodMenu.cookie: print("cookie") } or simply var menuItem: FastFoodMenu = FastFoodMenu.hamburger(patties: 2) switch menuItem { case .hamburger: print("burger") case .fries: print("fries") case .drink: print("drink") case .cookie: print("cookie") }
use break to skip
var menuItem: FastFoodMenu = FastFoodMenu.hamburger(patties: 2) switch menuItem { case .hamburger: break case .fries: print("fries") case .drink: print("drink") case .cookie: print("cookie") }
use default
var menuItem: FastFoodMenu = FastFoodMenu.hamburger(patties: 2) switch menuItem { case .hamburger: print("burger") case .fries: print("fries") default: print("other") }
get associated data
var menuItem: FastFoodMenu = FastFoodMenu.drink("Coke", ounces: 32) switch menuItem { case .hamburger(let pattyCound): print("a burger with \(patthCound) patties") case .fries(let size): print("a \(size) order of fries") case .drink(let brand, let ounces): print("a \(ounces)oz of \(brand)") case .cookie: print("cookie") }
enum can have method but no storage and computed variable
enum FastFoodMenu { case hamburger(numberOfPatties: Int) case fries(size: FryOrderSize) case drink(String, ounces: Int) case cookie func isIncludedInSpecialOrder(number: Int) -> Bool { switch self { case .hamburger(let pattyCound): return pattyCount == number case .fries, .cookie: return true case .drink(_, let ounces): return ounces == 16 } } var calories: Int {} }
modify self in enum, mutating is must since enum is value types (copy on write)
enum FastFoodMenu { ... mutating func switchToBeingACookie() { self = .cookie } }
Optional just a enum
enum Optional<T> { case none case some(<T>) }
Special Optional syntax in swift
The ‘not set’ case has special keyword: nil
The character ? is used to declare an Optional
the character ! is used to ‘unwrap’ the associated data if Optional is in the ‘set’
the keyword if can also used to conditionally get associated data (if let index = xxx …)
An optional declared with ! (instead of ?) will implicitly unwrap (add !) when access (eg. flipCoundIndex: UILabel!)
you can use ?? to create an expression which “default” to a value if an optional is not set (eg. return emoji[card.identifier] ?? “?”)
you can also use ? when accessing an optional to bail out of an expression midstream, this is called optional chaining
example of optional
#+begin_src
var hello: String? var hello: Optional<String> = .none
var hello: String? = “hello” var hello: Optional<String> = some(“hello”)
var hello: String? = nil var hello: Optional<String> = .none
var hello: String? = “Hi” switch hello {
print hello! case .none: // raise exception (crash!) case .some(let data): print(data) }
if let greeting = hello { switch hello {
print (greeting) case .some(let data): print(data) } else … case .none: // do … }
let x: String? = … switch x {
let y = x ?? “foo” case .none: y = “foo” case .some(let data): y = data }
let x: String? = … switch x {
let y = x?.foo()?.bar?.z 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 } } } #+end_src