Swift 枚举的用法

1、基本用法

//enum direction {
//    case north
//    case south
//    case west
//    case east
//}  等价于下面写法
enum direction {
    case north,south,west,east
}

var dir = direction.north
dir = .south
dir = direction.west
//print(dir)

switch dir  {
case .south :
    print("south")
case .north :
    print("north")
case .east :
    print("east")
case .west :
    print("west")
}
//输出 west

2、关联值 (associated Values )

enum score {
    case point (Int)
    case grade (Character)
}
var sc = score.point(10)
sc = .grade("A")

//print(sc)

switch sc {
case let .point(i):
    print("分数\(i)")
case let .grade(i):
    print("等级\(i)")
}
//输出 等级A

enum date{
    case ymd (Int,Int,Int)
    case string (String)
}

var d = date.ymd(2005, 8, 8)
//d = .string("2008-8-8")

switch d {
case let .string(i):
    print("sting时间\(i)")
case let .ymd(a, b, c): // .ymd(let a,let b,let c):
      print("时间\(a)-\(b)-\(c)")
}
//时间2005-8-8 输出

3、原始值 rawValue

enum grade :String{
    case perfect = "A"
    case great = "B"
    case good = "C"
    case bad = "D"
}
print(grade.perfect.rawValue) //A
print(grade.great.rawValue)//B
print(grade.good.rawValue)//C
print(grade.bad.rawValue)//D

隐式原始值

//t如果枚举初始值类型为int \ String  Swift 会为其自动分配原始值
enum time :Int { //默认值 0 1 2
   case morning , afternoon ,evening
}
print(time.afternoon.rawValue) // 1
enum direction : String { //默认值就是当前字符串
    case north,south,west,east
}

4、递归枚举

indirect enum mathExpor{
    case num(Int)
    case sum(mathExpor,mathExpor)
    case difference(mathExpor,mathExpor)
}
let one = mathExpor.num(8)
let two = mathExpor.num(5)
let three = mathExpor.num(3)
let sum = mathExpor.sum(one, two)
let difference = mathExpor.difference(sum, three)

func calcute (_ math:mathExpor )->Int{
    switch math {
    case let .num(i):
        return i
    case let .sum(i, j):
        return calcute(i)+calcute(j)
    case let .difference(i, j):
        return calcute(i)-calcute(j)
    }
    
}
print(calcute(difference)) //10

5、MemoryLayout 获取数据类型占用的内存大小

enum passWord{
    case num(Int,Int,Int,Int) // int 8字节 * 4 = 32
    case  string              // 分配一个字节
}
print(MemoryLayout<passWord>.stride) //40 分配占用空间大小
print(MemoryLayout<passWord>.size) //33 实际占用空间大小
print(MemoryLayout<passWord>.alignment) //8 对齐参数

var pwd  = passWord.string
print(MemoryLayout.size(ofValue: pwd))  // 33
print(MemoryLayout.stride(ofValue: pwd)) //40
print(MemoryLayout.alignment(ofValue: pwd)) //8
pwd = .num(100, 1, 2, 40)
print(MemoryLayout.size(ofValue: pwd))  // 33
print(MemoryLayout.stride(ofValue: pwd)) //40
print(MemoryLayout.alignment(ofValue: pwd)) //8
import UIKit

enum number:Int,CaseIterable {
    case one
    case two
    case three
    case four
}
for c in number.allCases{
    print(c)
}
print(number.one.rawValue)
/*
 one
 two
 three
 four
 */
// 如果要遍历枚举 需要让枚举遵循 CaseIterable 协议
enum value:Int {
    case one = 1
    case two
    case three
    case four
}
print(value.four.rawValue)
// 系统能自动推断后面的类型 若不给one 赋值初始值 则默认为0
value(rawValue: 2) // 根据rawValue 反向推断枚举类型

let o:value = .one
if o == .one {
    print("是one")
}
print(o.rawValue) //1


enum Barcode {
    case upc(Int, Int, Int, Int)
    case qrCode(String)
}

var productBarcode = Barcode.upc(8, 85909, 51226, 3)
productBarcode = .qrCode("ABCDEFGHIJKLMNOP")

switch productBarcode {
//case .upc(let numberSystem, let manufacturer, let product, let check):
//    print("UPC: \(numberSystem), \(manufacturer), \(product), \(check).")
case let.upc( numberSystem, manufacturer,product,check):
    print("UPC: \(numberSystem), \(manufacturer), \(product), \(check).")
case .qrCode(let productCode):
    print("QR code: \(productCode).")
}
/*
 关联值枚举 枚举在赋值是需传入参数
 在初始化枚举的时候 不设置初始值
 在需要的时候才给枚举设置关联值
 后面用到枚举类型时 就能使用到枚举的关联值
 */
if case let.qrCode(value) = productBarcode {
    print(value)
}