//枚举:为一组相关的值定义了一个共同的类型,可以在代码中以类型安全的方式来使用
//C语言中枚举值会分配一组整型来关联,Swift中枚举更加灵活,可以不必给枚举成员提供值,如果提供值,该值得类型可以是字符串、字符或一个整型值或浮点数。
//枚举语法示例1:罗盘的方向
enum CompassPoint{
case north
case south
case east
case west
}
enum CompassPoint2 {//也可以用一个case将所有枚举值都写在一行,用逗号隔开
case north,south,east,west
}
//在Swift中,枚举类型是一等类型,枚举的名字以大写字母开头
var norDirection = CompassPoint.north
norDirection = .east//当变量norDirection类型已知时,再次为其赋值,可以省略枚举类型名,直接使用点语法
//可以使用switch语句匹配单个枚举值:在判断一个枚举值时,switch语句必须穷举所有情况,否则就无法通过编译,强制穷举确保了枚举成员不会被意外泄漏。
switch norDirection {
case .north:
print("罗盘定位为-北方")
case .south:
print("罗盘定位为-南方")
case .east:
print("罗盘定位为-东方")
case .west:
print("罗盘定位为-西方")
}
switch norDirection {//不需要匹配每个枚举成员的时候,可以提供一个default来涵盖其他枚举成员完成穷举。
case .east:
print("去东方")
default:
print("方向错了")
}
//关联值:
enum Barcode {//条形码
case upc(Int,Int,Int,Int) //upc编码,分四个部分:1位数字系统、5位厂商编码、5位产品编码、1位检查位
case qrCode(String)//二维码:最多2953个字符的字符串
}
//以上可以理解为:定义一个名为Barcode的枚举类型,它的成员值有两个:1.具有(Int,Int,Int,Int)类型关联值的upc;2.具有String类型关联值的qrCode.
var productBarcode = Barcode.upc(8, 85909, 51226, 3)//创建了一个productBarcode变量
productBarcode = .qrCode("ABCDEFGHIJKLMNO")//同一个商品可以被分配一个不同类型的条形码
//Barcode类型可以存储一个.upc和一个.qrCode,但在同一时间只能存储这两个值中的一个
switch productBarcode {
case .upc(let numberSystem, let manufacturer, let product, let check):
print("upc码:\(numberSystem),\(manufacturer),\(product),\(check)")
case .qrCode(let productCodeStr):
print("二维码:\(productCodeStr)")
}
//打印结果:二维码:ABCDEFGHIJKLMNO
//如果枚举成员的所有关联值都是常量或者变量,可以在成员名称前标注一个let或var。上面的可以写为:
switch productBarcode {
case let .upc(numberSystem,manufacturer,product,check):
print("upc码:\(numberSystem),\(manufacturer),\(product),\(check)")
case let .qrCode(productCodeStr):
print("二维码:\(productCodeStr)")
}
//原始值
//枚举成员可以被默认值(原始值)预填充,这些原始值的类型必须相同,可以是字符串、字符、或者任意整型值或浮点型值,每个原始值在枚举声明中必须是唯一的。
enum ASCIICode: Character{//枚举类型 ASCIICode 的原始值类型被定义为 Character 字符类型,并设置了一些较常见的ASCII控制字符。
case tab = "\t"
case lineFeed = "\n"
case carriageReturn = "\r"
}
//原始值的隐式赋值:原始值为字符串或整数类型时,不需要显式为每个枚举成员设置原始值,Swift会自动赋值,例如:
enum CompassPoint3: String{//字符串类型枚举的的原始值就是该枚举成员的名称,例如CompassPoint3.south 的隐式原始值就是south
case north,south,east,west
}
//当整数作为原始值是,隐士赋值的值依次递增1,如果第一个枚举成员没有设置原始值,其原始值将为0
enum Planet: Int{//行星在太阳系的顺序:水星、金星、地球、火星、木星、土星、天王星、海王星
case mercury = 3,venus,earth,mars,jupiter,saturn,uranus,neptune
}
let venusValue = Planet.venus.rawValue//通过.rawValue来获取原始值
print("地球的原始值是:\(venusValue)====罗盘点的原始值为:\(CompassPoint3.south.rawValue)")//如果mercury不是指原始值,默认其为0
//使用原始值的初始化方法来创建一个新的枚举实例
let possiblePlanet = Planet(rawValue: 7)//possiblePlanet 类型为 Planet? 值为 Planet.uranus;也有可能是nil
if let somePlanet = Planet(rawValue: 11) {//试图从Planet枚举中找到初始值为11的那颗行星
switch somePlanet {
case .earth:
print("是地球")
default:
print("不是地球,但有这颗行星")
}
}else{
print("没有找到这颗行星")
}
//递归枚举 : 有一个或多个枚举成员 使用 该枚举类型的实例 作为关联值;
//使用递归枚举是,编译器会插入一个间接层,可以在枚举成员前加上indirect来表示该成员可递归
enum ArithmeticExpression {//算术表达式:存储了三种算术表达式,纯数字、两个表达式相加、两个表达式相乘
case number(Int)
indirect case addition(ArithmeticExpression,ArithmeticExpression) //加
indirect case multiplication(ArithmeticExpression,ArithmeticExpression)//乘
}
//也可以在枚举类型的开头加上 indirect 关键字来表明该枚举所有成员都是可递归的
indirect enum ArithmeticExpression2{
case number(Int)
case addition(ArithmeticExpression,ArithmeticExpression) //加
case multiplication(ArithmeticExpression,ArithmeticExpression)//乘
}
//枚举成员addition 和multiplication 的关联值也是算术表达式
let two = ArithmeticExpression.number(2)
let four = ArithmeticExpression.number(4)
let five = ArithmeticExpression.number(5)
let sum = ArithmeticExpression.addition(four,five)// 4 + 5
let product = ArithmeticExpression.multiplication(sum, two) //(4 + 5) * 2
func evaluate(_ expression: ArithmeticExpression) -> Int {//参数为ArithmeticExpression类型,返回值 Int型
switch expression {
case let .number(value)://如果是number 就返回 value
return value
case let .addition(left,right): //如果是加法 就返回两个值相加的结果
return evaluate(left) + evaluate(right)
case let .multiplication(left, right): //如果是乘法, 就返回两个值相乘
return evaluate(left) * evaluate(right)
}
}
print(evaluate(two)) // 2
print(evaluate(sum)) // 4+ 5 9
print(evaluate(product))//(4 + 5) * 2 18
网友评论