自定义数据类型 --- 枚举类型全解(swift2.3)

自定义数据类型 — 枚举(swift)

下面简单的介绍枚举这一自定义数据类型的应用

  1. 枚举的基本语法

  2. 枚举中rawValue应用

  3. 枚举中associatedValue应用

  4. 可选型的实质类型就是枚举

  5. 枚举的递归应用

一:枚举的基础语法

import UIKit

//: 1.定义一个类型为Month的枚举类型,这个枚举类型有12种可能性
enum Month {
    case January,February,March,April,May, June,July,August, September,October,November,December
}

 //2.那么枚举这种自定义数据类型,可以像类一样,定义一个变量,这里可以不需要写month的数据类型,因为swift会infer month的数据类型为Month
let curMonth = Month.October

 //: 3.下面我们定义一个函数,将函数参数的类型设置为我们定义的枚举类型,函数的返回值为String类型
func season( month: Month) ->String{

    switch month { //在这里要注意的是:switch选择的永远都是参数的变量名,不是数据类型

    case .January: //case 是判断这个枚举变量是哪一种可能性

        return "1"

    case .February: //由于switch判断的是month这个枚举类型的可能性,month一共有12种可能性,我这里将其一一的列举出来了,那么就不需要defaultreturn "2"

    case .March :

        return "3"

    case .April :

        return "4"

    case .May :

        return "5"

    case .June :

        return "6"

    case .July :

        return "7"

    case .August :

        return "8"

    case .September :

        return "9"

    case .October :

        return "10"

    case .November :

        return "11"

    case .December :

        return "12"
    }


}

//调用刚刚定义的函数,由于这个函数可以传入一个参数,那么将Month.October的变量名curMonth传入进去,来通过函数中的switch来判断这个枚举变量是哪一种情况
season(curMonth)

二:枚举中rawValue应用

1.通过枚举类型的可能性获取肯能性的int值

//由于枚举类型的每一种可能性都与一个int类型的整数相互关联,那么在函数中,通过参数的点语法的rawValue可以拿到这个枚举变量的rawValue值
 // 定义raw value,完全定义
enum Month: Int{//这样就手动的将Month中的各种可能性和int结合起来了
    case January = 1
    case February = 2
    case March = 3
    case April = 4
    case May = 5
    case June = 6
    case July = 7
    case August = 8
    case September = 9
    case October = 10
    case November = 11
    case December = 12
}

//定义一个函数,计算传入一个Month变量的参数后,计算出还剩下多少月
func howManyMonthesleft( cruMonth: Month) -> Int{

    return 12 - cruMonth.rawValue

}

//定义一个枚举变量
let curMonth = Month.July

//将curMonth作为函数的参数调调用,这个简单的例子说明了枚举类型的可能性可以与int一一对应
howManyMonthesleft(curMonth)

2.通过枚举类型的rawValue获取肯能性值

//由于枚举类型的每一种可能性都与一个int类型的整数相互关联,那么在函数中,通过参数的点语法的rawValue可以拿到这个枚举变量的rawValue值
 // 定义raw value,完全定义
enum Month: Int{//这样就手动的将Month中的各种可能性和int结合起来了
    case January = 1
    case February = 2
    case March = 3
    case April = 4
    case May = 5
    case June = 6
    case July = 7
    case August = 8
    case September = 9
    case October = 10
    case November = 11
    case December = 12
}

//定义一个函数,计算传入一个Month变量的参数后,计算出还剩下多少月
func howManyMonthesleft( cruMonth: Month) -> Int{

    return 12 - cruMonth.rawValue

}

let input = 11



//通过枚举类型的构造函数定义枚举变量,此时定义的变量是一个可选型变量
let curMonth = Month(rawValue: input)

//将curMonth作为函数的参数调调用,这个简单的例子说明了枚举类型的可能性可以与int一一对应
if let curMonth = curMonth{//将可选型curMonth进行解包,得到的是一个Month类型的变量
howManyMonthesleft(curMonth)
}

3.在枚举类型的定义中,也可以没给可能性绑定int值,这样系统会自动将各种可能性按0开始编码

enum Month: Int{//这样就手动的将Month中的各种可能性和int结合起来了
    case January
    case February
    case March
    case April
    case May
    case June
    case July
    case August
    case September
    case October
    case November
    case December
}

//定义一个函数,计算传入一个Month变量的参数后,计算出还剩下多少月
func howManyMonthesleft( cruMonth: Month) -> Int{

    return 12 - cruMonth.rawValue

}

let input = 11



//通过枚举类型的构造函数定义枚举变量,此时定义的变量是一个可选型变量
let curMonth = Month(rawValue: input)

//将curMonth作为函数的参数调调用,这个简单的例子说明了枚举类型的可能性可以与int一一对应
if let curMonth = curMonth{//将可选型curMonth进行解包,得到的是一个Month类型的变量
howManyMonthesleft(curMonth)//这样计算出来的值也是对的
}

4.枚举类型的可能性绑定的类型也可以是String类型,不一定都是int类型

// 使用String作为raw value有默认值
enum ProgrammingLanguage2: String{
    case Swift = "swift"
    case ObjectiveC = "Objective-C"
    case C = "c"
    case Java = "java"
}

let myFavoriteLanguage2: ProgrammingLanguage2 = .Swift
print( "\(myFavoriteLanguage2.rawValue) is my favorite language.")

三:枚举中associatedValue应用
1.枚举类型中单个关联值(基本类型关联值)

// Associate Value 和 Raw value 只能存在一个
enum ATMStatus{//如果是设置枚举变量的Associate Value,就不能设置枚举变量的Raw Value.这里将枚举类型的各种可以性关联不同的数据类型
    case Success(Int)
    case Erro(String)
    case Wainting //也可以不关联任何职

}

//下面我们第一个函数,函数的参数类型为int,放回值为ATMStatus枚举类型

var balance = 1000

func withDraw(amount: Int) -> ATMStatus {

    if balance >= amount{

        balance -= amount

        return .Success(balance)

    }else{

        return .Erro("your account is not enough")
    }

}

//解包的方式有两种:一种是刘老师说的,一种是Stanford大学白胡子老头说的
let result = withDraw(1009)//但是现在返回给我们的还是一个枚举类型的肯能性,那么需要将可能性里面的关联值解包出来

switch result{

case let .Success(newBalance):
    print(newBalance)
case let .Erro(newString):
    print(newString)
case .Wainting:
    print("please wait a minute")
}

//方法二:Stanford大学白胡子老头(随便提一句,解析关联值不是必须的)
let result1 = withDraw(100)

switch result1{

case .Success(let newBalance):

    print(newBalance)

case .Erro(let newString):

    print(newString)

case .Wainting:

    break

}

2.多个关联值(可以是tuple类型,也可以是函数类型 —>在Stanford大学有提到)


func multiply(op1: Double, op2: Double) -> Double {


    return op1 * op2



}

// Associate Value 和 Raw value 只能存在一个
enum ATMStatus{//如果是设置枚举变量的Associate Value,就不能设置枚举变量的Raw Value.这里将枚举类型的各种可以性关联不同的数据类型
    case Success(Int)
    case Erro(String)
    case Wainting //也可以不关联任何职

}

//下面我们第一个函数,函数的参数类型为int,放回值为ATMStatus枚举类型

var balance = 1000

func withDraw(amount: Int) -> ATMStatus {

    if balance >= amount{

        balance -= amount

        return .Success(balance)

    }else{

        return .Erro("your account is not enough")
    }

}

//解包的方式有两种:一种是刘老师说的,一种是Stanford大学白胡子老头说的
let result = withDraw(1009)//但是现在返回给我们的还是一个枚举类型的肯能性,那么需要将可能性里面的关联值解包出来

switch result{

case let .Success(newBalance):
    print(newBalance)
case let .Erro(newString):
    print(newString)
case .Wainting:
    print("please wait a minute")
}

//方法二:Stanford大学白胡子老头(随便提一句,解析关联值不是必须的)
let result1 = withDraw(100)

switch result1{

case .Success(let newBalance):

    print(newBalance)

case .Erro(let newString):

    print(newString)

case .Wainting:

    break

}



//定义一个有多个关联值的枚举类型
enum Shape {
    case square( Double)

    case rectangle( Double, Double)

    case circle( Double,  Double, Double)

    case simpleOperation(Double ->Double)//sqrt:求一个数的平方根(stanford University)

    case point

    case multiple((Double,Double) ->Double) } //定义这个枚举类型的变量 let rectangle = Shape.rectangle(10, 10) //定义枚举变量的目的是作为函数的参数 let foo = Shape.simpleOperation(sqrt) let square = Shape.square(20) let circle = Shape.circle(0, 0, 30) let point = Shape.point var result2 = 9.0 var result3 = 10.0 let fooo = Shape.multiple(multiply) //定义一个函数来计算每一个图形的面积 func culculateShape(shape: Shape) -> Double {

    switch shape {
    case .rectangle(let width,let height)://stanford University

        return width * height

    case let .circle(_, _, radius)://imooc University

        return M_PI * radius * radius

    case .square(let side):

        return side * side

    case .simpleOperation(let food):

        return  food(result2)

    case .point:

        return 0

    case .multiple(let fooo):

        return fooo(result2,result3)

    }


}

var area = culculateShape(rectangle)

var area1 = culculateShape(square)

var area2 = culculateShape(circle)

var area3 = culculateShape(point)

var resultNumble = culculateShape(foo)//这里将sqrt函数作为关联值

var re = culculateShape(fooo)

四:可选型的实质类型就是枚举

var age: Int? = 12

print(age)

age = nil

print(age)

//其实swift内部就是封装了一个类型名为optional的枚举型,那么person就是一个枚举型变量
var person = Optional.Some("尹欢一")

person = .None

//那么在赋值的时候,可以直接赋值

person = "你好,尹欢一"

person = nil

//那么可选型的解包方法就有两种

//使用switch解包
switch person{

case .Some(let name):

    print(name)

case .None:

    print("没有解包")

}

//2.赋值解包

if let person = person{

    print(person)

}else{

print("nil")

}

五:枚举的递归应用


// 枚举递归,使用indirect关键字
enum ArithmeticExpression{

    case Number(Int)
    indirect case Addition( ArithmeticExpression , ArithmeticExpression )
    indirect case Multiplication( ArithmeticExpression , ArithmeticExpression )
}

// 也可以直接将indirect关键字放在整个enum前面
indirect enum ArithmeticExpression2{

    case Number(Int)
    case Addition( ArithmeticExpression , ArithmeticExpression )
    case Multiplication( ArithmeticExpression , ArithmeticExpression )
}


// (5 + 4) * 2
let five = ArithmeticExpression.Number(5)
let four = ArithmeticExpression.Number(4)
let sum = ArithmeticExpression.Addition(five, four)
let two = ArithmeticExpression.Number(2)
let product = ArithmeticExpression.Multiplication(sum, two)


func evaluate(expression: ArithmeticExpression) -> Int {
    switch expression {
    case  .Number(let value):
        return value
    case  .Addition(let left, let right):
        return evaluate(left) + evaluate(right)//由于不知道第一次解包出来的是不是一个数,所以在这里将解包出来的表达是再调用这个函数,再进行解析,这样就实现了递归操作
    case  .Multiplication(let left, let right):
        return evaluate(left) * evaluate(right)
    }
}


evaluate(product)

你可能感兴趣的:(swift)