// 递归枚举

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

// 如果你熟悉C语言, 你会知道在C语言中, 枚举会为一组整型值分配相关联的名称, swift 中的枚举更加的灵活, 不必给每一个枚举成员提供一个值,如果给枚举成员提供一个值 (称为原始值), 则该值的类型可以是字符串,字符, 或者是一个整型值或浮点数,

// 此外, 枚举成员可以指定任意类型的关联值存储到枚举成员中, 你可以在一个枚举中定义一组相关的枚举成员, 每一个枚举成员都可以有适当类型的关联值,

// 枚举语法

// 使用enum 关键字来创建枚举并且把它们的真个定义放在一堆大括号内

enum SomeEnumeration{

// 枚举定义放在这里

}

// 下面用枚举表示指南针四个方向的例子

enum CompassPoint {

case north

case south

case east

case west

}

// 枚举中定义的值 (如 north, south, east ,west) 是这个枚举的成员值(或成员), 你可以使用 case 关键字来定义一个新的枚举成员值

// 注意 : 与 C语言和 OC 不同, swift 的枚举成员在被创建时不会被赋予一个默认的整型值,在上面的 CompassPoint 例子中, north, south ,east 和 west 不会被隐式地赋值为0,1,2,3 ,相反,这些枚举成员本身就是完备的值,这些值的类型是已经是明确定义好的 CompassPoint 类型

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

enum Planet {

case mercuty, venus,earth, jupiter, saturn, uranus, neptune

}

// 每个枚举定义了一个全新的类型, 像 Swift 中其他类型一样, 他们的名字,应该以一个大字母开头, 给枚举类型起一个单数名字而不是复数名字, 以便于读起来更加容易理解

var directionToHead = CompassPoint.west

// directionToHead 的类型可以在它被 CompassPoint 的某个值初始化时推断出来, 一旦 directionToHead 被声明为 CompassPoint 类型, 你可以使用更简短的点语法将其设置为另一个 CompassPoint 的值,

directionToHead = .east

// 当 directionToHead 的类型已知时, 再次为其赋值可以省略枚举类型名, 在使用具有显式类型的枚举值时, 这种写法让代码有更好的可读性

// 使用 Swift 语句匹配枚举值

// 你可以使用 Swift 语句匹配单个值:

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")

default:

print("none")

}

// 在判断一个枚举类型的值时 ,Swift 语句必须穷举素有的情况, 当不需要匹配每个枚举成员的时候, 你可以提供一个 default 分支来涵盖所有未明确处理的枚举成员

let somePlanet = Planet.earth

switch somePlanet {

case .earth:

print("Mostly harmless")

default:

print("Not a safe place for humans")

}

// 关联值

// 有时候能够把其他类型的关联值和成员值一起存储起来会更有用, 这能让你连同成员值一起存储额外的自定义信息,并且你每次在代码中使用该枚举成员时, 还可以修改这个关联值

// 你可以定义 Swift 枚举来存储任意类型的关联值, 如果需要的话, 每个枚举成员的关联值类型可以各部相同, 枚举的这个特性跟其他语言中的可识别联合, 标签联合, 或者变体相似

// 例如: 假设一个库存跟踪系统需要利用不同类型的条形码来跟踪商品,有四个数字,其他商品上标有 QR 码格式的二维码, 它是可以使用任何字符的字符串

// 在 Swift 中, 使用如下方式定义表示两种商品条形码的枚举

enum Barcode{

case upc(Int,Int,Int,Int)

case qrCode(String)

}

// 以上可以这么理解 : "定义一个名为 BarCode 的枚举类型, 它的一个成员是具有 (Int, Int, Int, Int) 类型关联值的upc, 另一个成员是具有 String 类型关联值的 qrCode"

// 这个定义不提供任何 Int 或者 String 类型的关联值, 它只是定义了, 当 BarCode 常量和变量等于 Barcode.upc 或者 Barcode.qrcode 时, 可以存储的关联值的类型

// 然后可以使用任意一种条形码类型创建新的条形码, 例如:

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

// 上面的例子创建了一个名为 productBarcode 的变量, 并将 Barcode.upc 赋值给它,

// 同一个商品可以被分配一个不同类型的条形码, 例如:

productBarcode = .qrCode("BJUIBHYUGVUTYFVFY")

// 这时,原始的 Barcode.upc 和其整数关联值被新的 Barcode.qrCode 和其字符串关联值所替代, Barcode 类型的常量和变量可以存储一个 .upc 或者一个 .qrCode,(连同他们的关联值), 但是在同一时间只能存储两个值中的一个

// 像先前那样,可以使用一个 switch 语句来检查不同的条形码类型。然而,这一次,关联值可以被提取出来作为 switch 语句的一部分。你可以在switch的 case 分支代码中提取每个关联值作为一个常量(用let前缀)或者作为一个变量(用var前缀)来使用:

switch productBarcode {

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

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

case .qrCode(let productCode):

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

}

// 打印 "QR code: ABCDEFGHIJKLMNOP."

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

switch productBarcode {

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

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

case let .qrCode(productCode):

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

}

// 输出 "QR code: ABCDEFGHIJKLMNOP."

// 原始值

// 在上个例子中, 演示了如何声明存储不同类型关联值的枚举成员, 作为关联值的替代选择, 枚举成员可以被默认值 (称为原始值) 预填充, 这些原始值的类型必须相同

// 原始值 可以是字符串, 字符,或者任意整型或是浮点型, 每个原始值在枚举声明中必须唯一的.

// 注意 : 原始值和关联值是不同的,原始值是在定义枚举是被预先填充的值, 对于一个特定的枚举成员,它的原始值始终不变, 关联值是创建一个基于枚举成员的变量或是常量是才设置的值, 枚举成员的关联值可以变化

// 原始值的隐式赋值

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

// 例如,当使用整数作为原始值时,隐式赋值的值依次递增 1, 如果第一个枚举成员没有设置原始值, 其原始值将为0

enum Planet2: Int {

case mercury = 1, venus, earth, mars, jupiter, saturn, uranus, neptune

}

// 在上面的例子中,Plant.mercury的显式原始值为1,Planet.venus的隐式原始值为2,依次类推。

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

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

enum CompassPoint2: String {

case north, south, east, west

}

// 上面的例子中, CompassPoint2.south 拥有隐式原始值 south ,依次类推

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

let earthsOrder = Planet2.earth.rawValue

let sunsetDirection = CompassPoint2.west.rawValue

// 使用原始值初始化枚举实例

// 如果在定义枚举类型的时候使用了原始值, 那么将会自动获得一个初始化方法, 这个方法接收一个叫做 rawValue 的参数,参数类型即为原始值类型, 参数类型即为原始值的类型, 返回值则是枚举成员或是 nil, 你可以使用这个初始化方法来创建一个新的枚举实例

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

let possiblePlanet = Planet2(rawValue: 7)

// 然而, 并非所有 Int 值都可以找到一个匹配的枚举成员, 因此, 原始值构造器总是返回一个可选的枚举成员, 在上面的例子中, possiblePlanet 是 Planet2? 类型, 或者说是 '可选的 Planet2'

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

// 如果你试图寻找一个位置 为 11 的枚举成员, 通过原始值构造器返回可选的 Planet2 值将是 nil

// 递归枚举

// 递归枚举是一种枚举类型, 它有一个或多个枚举成员使用该枚举类型的实例作为关联值,使用递归枚举时,编辑器会插入一个间接层, 你可以在枚举成员前加上 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的关联值也是算术表达式——这些关联值使得嵌套表达式成为可能。例如,表达式(5 + 4) * 2,乘号右边是一个数字,左边则是另一个表达式。因为数据是嵌套的,因而用来存储数据的枚举类型也需要支持这种嵌套——这意味着枚举类型需要支持递归。下面的代码展示了使用ArithmeticExpression这个递归枚举创建表达式(5 + 4) * 2

let five = ArithmeticExpression.number(5)

let four = ArithmeticExpression.number(4)

let sum = ArithmeticExpression.addition(five, four)

let product = ArithmeticExpression.multiplication(sum, ArithmeticExpression.number(2))

Swift 学习- 09 -- 枚举的更多相关文章

  1. Swift学习-枚举(Enumerations)的使用方法

    Swift学习-枚举的使用方法 枚举的使用语法: enum someEnumer { // 枚举的成员值 } 以下是方向的一个例子: enum direction { case Up case Dow ...

  2. Swift 学习笔记 (枚举)

    枚举为一种相关值定义了一个通用类型,从而可以让你在代码中类型安全的操作这些值. Swift中的枚举很灵活,不需要给每一个枚举中的成员都提供值.如果一个值(所谓 原时值) 要被提供给每一个枚举成员,那么 ...

  3. swift学习笔记3——类、结构体、枚举

    之前学习swift时的个人笔记,根据github:the-swift-programming-language-in-chinese学习.总结,将重要的内容提取,加以理解后整理为学习笔记,方便以后查询 ...

  4. 【Swift学习】Swift编程之旅---枚举(十二)

    枚举为一组相关的值定义一个共同的类型,并允许您在代码中的以类型安全的方式中使用这些值,在 Swift 中,枚举类型是一等(first-class)类型.它们采用了很多传统上只被类所支持的特征,例如计算 ...

  5. Swift学习笔记 - 位移枚举的按位或运算

    在OC里面我们经常遇到一些枚举值可以多选的,需要用或运算来把这些枚举值链接起来,这样的我们称为位移枚举,但是在swift里面却不能这么做,下面来讲解一下如何在swift里面使用 OC的位移枚举的区分 ...

  6. swift学习 - 计时器

    swift学习之计时器 这个demo主要学习在swift中如何操作计时器(Timer),按钮(UIButton),文本(Label) 效果图: 代码 import UIKit class ViewCo ...

  7. swift 学习之自动引用计数

    swift 学习之自动引用计数 学习和研究的主要是"实例对象和实例对象直接的相会强引用所产生的内从泄漏"和"使用闭包产生的强引用造成的内存泄漏" 注意:只有以引 ...

  8. Swift学习目录

    本学习基于苹果官方Swift学习材料,保留了原版90%左右的内容(一些项目开发中基本不用的知识点没有整理),并根据理解进行整理.如对原版感兴趣,可以直接单击链接阅读和学习. 第一部分 基础篇 1.基本 ...

  9. 【swift学习笔记】二.页面转跳数据回传

    上一篇我们介绍了页面转跳:[swift学习笔记]一.页面转跳的条件判断和传值 这一篇说一下如何把数据回传回父页面,如下图所示,这个例子很简单,只是把传过去的数据加上了"回传"两个字 ...

随机推荐

  1. (9)EvenOddJump

    一.问题描述 一只青蛙从数组(A)的每一个元素向数组尾部跳动.跳动规则如下: 当奇数跳的时候,就是第1.3.5.7....次进行移动时候,移动规则A[i] <= A[j],  并且A[j] = ...

  2. pyqt5-QWidget坐标系统和大小

    获取坐标和尺寸: 坐标的获取视频教程:https://v.qq.com/x/page/t085892mzh9.html  x()    y()   返回控件的坐标 相对于父控件的坐标(窗口框架左上角) ...

  3. luogu P4899 [IOI2018] werewolf 狼火

    传送门 首先很显然,从人形起点出发能到的点和狼形能到终点的点都是一个联通块,如果能从起点到终点则说明这两个联通块有交 这个时候可以请出我们的克鲁斯卡尔重构树,即对原图分别建两棵重构树,一棵边权为两端点 ...

  4. Ubuntu18.04安装搜狗拼音输入法皮肤透明解决方法

    解决方法: 去搜狗输入法官网下载一个新的皮肤,然后右键用“搜狗输入法”打开,就解决了!!!

  5. 影子节点 shadowDOM

    示例: <video controls autoplay name="media"> <source id="mp4" src="t ...

  6. org.springframework.beans.factory.CannotLoadBeanClassException-估计mapper出参 和 po字段不对应了

    DEBUG [localhost-startStop-1] - Ignoring bean class loading failure for bean 'itemsService'org.sprin ...

  7. 超级简单的Android Studio jni 实现(无需命令行)【转载】

    原文: http://www.jianshu.com/p/e689d0196a17 1.配置Anroid Studio(这步是关键) 使用[command+,] 打开Preferences,选择Ext ...

  8. C/C++ assert()函数用法总结

    1. 简介 assert宏的原型定义在<assert.h>中,其作用是如果它的条件返回错误,则终止程序执行. 原型定义: #include <assert.h>void ass ...

  9. MySql联合查询

    将多条查询语句的结果合并为一个结果 *多表查询是横向连接,联合查询是纵向连接. 语法: 查询语句1 union 查询语句2 union 查询语句3 *union关键字默认去重,union all包含重 ...

  10. HDOJ 4267 A Simple Problem with Integers (线段树)

    题目: Problem Description Let A1, A2, ... , AN be N elements. You need to deal with two kinds of opera ...