swift 枚举(笔记)

/******************** 枚举Enumerations ********************/


/*

枚举语法 Enumeration Syntax

使用Switch语句匹配枚举值 Matching Enumeration Values with a Switch Statement

关联值 Associated Values

原始值 Raw Values

递归枚举 Recursive Enumerations

*/


// 枚举为一组相关的值定义了一个共同的类型,使你可以在你的代码中以类型安全的方式来使用这些值

// Swift中的枚举值更加灵活,不必给每一个枚举成员提供值.如果提供了(原始值),则该值的类型是字符串,字符或是一个整形值或浮点值


// 枚举成员可以指定任意类型的关联值存储到枚举成员中,就像其他语言中的联合体unions和变体variants.每一个枚举成员都可以有适当类型的关联值


// Swift,枚举类型是一等(first-class)类型,他们采用了很多再传统上只做类所支持的特性.

// 计算机属性:用于提供枚举值的附加信息

// 实例方法:用于提供和枚举值相关联的功能

// 枚举也可以定义构造函数提供一个初始值,可以在原始实现的基础上扩展他们的功能,还可以遵循协议类提供标准的功能



// 枚举语法

// 使用enum关键字创建

enum SomeEnumeration {

    // 枚举定义放在这

}


// 指南针方向

enum CompassPoint {

    case North

    case South

    case East

    case West

}

CompassPoint.East

// case 关键字来定义一个新的枚举成员值

// 这些枚举值不会再直接赋予一个整形的0,1,2,3,这种值了,他们本身就是完备的值,这些值的类型是已经明确定义好的CompassPoint类型


// 多个成员值可以出现在同一行,用逗号隔开

enum Planet {

    case Mercury,Venus,Earth,Mars,Jupiter,Saturn,Uranus,Neptune

}

var directionToHead = CompassPoint.North

// 一旦directionToHead被声明为Planet类型,那么可以更简略

directionToHead = .East

// 在使用具有显式类型的枚举值时,这种写法让代码具有更好的可读性


// 使用Switch语句匹配枚举值:

directionToHead = .South

switch directionToHead{

case .North:

    print("Lots of planets have a north")

case .South:

    print("Watch out for penguins")

case .East:

    print("Where the sun rises")

case .West:

    print("Where the skies are blue")

}

// 输出"Watch out for penguins"


// Switch语句必须穷举所有情况


let somePlanet = Planet.Earth

switch somePlanet{

case .Earth:

    print("Mostly harmless")

default:

    print("Not a safe place for humans")

}

// 输出Mostly harmless



// 关联值 Associated Values

enum Barcode {

    case UPCA(Int,Int,Int,Int)

    case QRCode(String)

}

// 理解为:

// 定义一个名为Barcode的枚举类型,它的一个成员值是具有(Int,Int,Int,Int)类型关联值的UPCA,另一个成员值是具有String类型关联值的QRCode

// 这个定义不提供任何Int String类型的关联值,他只是定义了,Barcode常量和变量等于Barcode.UPCABarcode.QRCode,可以存储的关联值的类型


var productBarcode = Barcode.UPCA(8,85909, 51226,3)

// 创建一个productBarcode的变量,并将Barcode.UPCA赋值给它,关联的元组为(8, 85909, 51226, 3)

// 还可以给个不同类型的值

productBarcode = .QRCode("ABCDEFGHIJKLMNOP")


// Barcode类型的常量和变量可以存储一个.UPCA或者一个.QRCode(连同它们的关联值),但是在同一时间只能存储这两个值中的一个

switch productBarcode{

case .UPCA(let numberSystem,let manufacturer,let product,let check):

    print("UPC-A: \(numberSystem), \(manufacturer), \(product), \(check).")

case .QRCode(let productCode):

    print("QR code:\(productCode).")

}

// 输出 "QR code:ABCDEFGHIJKLMNOP."


// 如果一个枚举成员的所有关联值都被提取为变量,或者都被提取为变量,为了简洁,可以在成员名称前标注一个let或者var:

switch productBarcode{

case let .UPCA(numberSystem,manufacturer,product,check):

    print("UPC-A: \(numberSystem), \(manufacturer), \(product), \(check).")

case let .QRCode(productCode):

    print("QR code:\(productCode).")

}



// 原始值 Raw Values


// 枚举成员可以被默认值(称为原始值)预填充,这些原始值的类型必须相同.

enum ASCIIControlCharcter:Character{

    case Tab = "\t"

    case UneFeed = "\n"

    case CarriageReturn = "\r"

}

// 原始值可以是字符串,字符,或者任意整型值或浮点型值.

// 原始值是在定义枚举时被预先填充的值,每个原始值在枚举声明中必须是唯一的.

// 关联值是创建一个基于枚举成员的常量或变量时才设置的值,枚举成员的关联值可以变化.



// 原始值的隐式赋值 Implicitly Assigned Raw Values


// 在使用原始值为整数或者字符串类型的枚举时,不需要显式的为每一个枚举成员设置原始值,Swift将会自动赋值

// 如果使用整数为原始值时,隐式赋值的值依次递增1,如果第一个枚举值没有设置原始值,那么原始值默认为0

// 下面的枚举值是对之前Planet这个枚举值的一个细化,利用整型的原始值来表示每个行星在太阳系中的顺序

enum Planet1:Int {

    case Mercury = 1,Venus,Earth,Mars,Jupiter,Saturn,Uranus,Neptune

}

// 当使用字符串作为枚举类型的原始值时,每个枚举成员的隐式原始值为该枚举成员的名称


// 下面的例子是CompassPoint枚举的细化,使用字符串类型的原始值来表达各个方向的名称

enum CompassPoint1:String{

    case North,South,East,West

}

// CompassPoint1.South的隐式原始值South,依次类推


// 使用枚举成员的rawValue属性可以访问该枚举成员的原始值:

let earthsOrder = Planet1.Earth.rawValue

print(earthsOrder)


let sunsetDirection = CompassPoint1.West.rawValue

/* 如果这个枚举不写类型,是不是就意味着没有默认值,点不出来rawValue */



// 使用原始值初始化枚举实例 (Initializing from a Raw Value)

// 如果在定义枚举类型的时候使用了原始值,那么将会自动获得一个初始化方法

// 如果这个方法接收一个叫做rawValue的参数,参数类型为原始值类型,返回值为枚举成员或nil.

// 你可以使用这个初始化方法来创建一个新的枚举实例


// 这个例子利用原始值7创建了枚举成员Uranus:

let possiblePlanet1 = Planet1(rawValue: 7)

// possiblePlanet1 类型为Planet? 值为Planet.Uranus


// 注意:原始值构造器是一个可失败构造器,因为并不是每一个原始值都有与之对应的枚举成员

// :如果你试图寻找一个位置为9的行星,通过原始值构造器返回的可选Planet值将是nil


let positionToFind = 9

if let somePlanet1 =Planet1(rawValue: positionToFind)

{

    switch somePlanet1{

    case .Earth:

        print("Mostly harmless")

    default:

        print("Not a safe place for humans")

    }

} else {

    print("There isn't a planet at position\(positionToFind)")

}

// 这个例子使用了可选绑定(optional binding),



// 递归枚举 (Recursive Enumerations)

// 当各种可能的可以被穷举时,非常适合使用枚举进行数据建模.

// 例如可以用枚举来表示用于简单整数运算的操作符,这些操作符让你可以讲简单的算术表达式,例如整数5,结合为更为复杂的表达式,例如5+4


// 算术表达式的一个重要特性:表达式可以嵌套使用.例如(5+4)*2

// 乘号右边是一个数字,左边则是另一个表达式.

// 因为数据是嵌套的,因而用来存储数据的枚举类型也需要支持这种嵌套----这意味着枚举类型需要支持递归


// 递归枚举(Recursive enumerations)是一种枚举类型,它有一个或多个枚举成员使用该枚举类型的实例作为关联值.使用递归枚举时,编译器会插入一个间接层,你可以在枚举成员前加上indirect来表示该成员可递归.

enum ArithmeticExpression{

    case Number(Int)

    indirect case Addition(ArithmeticExpression,ArithmeticExpression)

    indirect case Multiplication(ArithmeticExpression,ArithmeticExpression)

}

// 也可以在枚举开头加上indirect(间接的,迂回的,非直接了当的)关键字来表明它的所有成员都是可递归的

indirect enum ArithmeticExpression1{

    case Number(Int)

    case Addition(ArithmeticExpression,ArithmeticExpression)

    case Multiplication(ArithmeticExpression,ArithmeticExpression)

}

// 上面定义的枚举类型可以存储

//ArithmeticExpression.Multiplication(ArithmeticExpression.Multiplication(<#T##ArithmeticExpression#>, <#T##ArithmeticExpression#>), <#T##ArithmeticExpression#>)


// 上面定义的枚举类型可以存储三种算术表达式:纯数字,两个表达式相加,两个表达式相乘.枚举成员AdditionMultiplication的关联值也是算术表达式---这些关联值使得嵌套表达式成为可能

// 要操作具有递归性质的数据结构,使用递归函数是一种直接了当的方式,

// 例如:下面是一个对算术表达式求值的函数

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)

    }

}

// 计算(5 + 4) * 2

let five = ArithmeticExpression.Number(5)

let four = ArithmeticExpression.Number(4)

let two = ArithmeticExpression.Number(2)

print(evaluate(two))

let sum = ArithmeticExpression.Addition(five,four)

let product = ArithmeticExpression.Multiplication(sum,two)

print(evaluate(product))


// 该函数如果遇到纯数字,就直接返回该数字的值,如果遇到的是加法或者是乘法,就分别计算左右的值,然后进行计算



// 初学者交流群,本群禁止闲扯,我们只是一群基础想进步的人

// 群号 149964858


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值