Swift 学习- 09 -- 枚举
// 递归枚举
// 美家居为一组相关的值定义了一个共同的类型, 使你可以在代码中以类型安全的的方式使用这些值.
// 如果你熟悉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 -- 枚举的更多相关文章
- Swift学习-枚举(Enumerations)的使用方法
Swift学习-枚举的使用方法 枚举的使用语法: enum someEnumer { // 枚举的成员值 } 以下是方向的一个例子: enum direction { case Up case Dow ...
- Swift 学习笔记 (枚举)
枚举为一种相关值定义了一个通用类型,从而可以让你在代码中类型安全的操作这些值. Swift中的枚举很灵活,不需要给每一个枚举中的成员都提供值.如果一个值(所谓 原时值) 要被提供给每一个枚举成员,那么 ...
- swift学习笔记3——类、结构体、枚举
之前学习swift时的个人笔记,根据github:the-swift-programming-language-in-chinese学习.总结,将重要的内容提取,加以理解后整理为学习笔记,方便以后查询 ...
- 【Swift学习】Swift编程之旅---枚举(十二)
枚举为一组相关的值定义一个共同的类型,并允许您在代码中的以类型安全的方式中使用这些值,在 Swift 中,枚举类型是一等(first-class)类型.它们采用了很多传统上只被类所支持的特征,例如计算 ...
- Swift学习笔记 - 位移枚举的按位或运算
在OC里面我们经常遇到一些枚举值可以多选的,需要用或运算来把这些枚举值链接起来,这样的我们称为位移枚举,但是在swift里面却不能这么做,下面来讲解一下如何在swift里面使用 OC的位移枚举的区分 ...
- swift学习 - 计时器
swift学习之计时器 这个demo主要学习在swift中如何操作计时器(Timer),按钮(UIButton),文本(Label) 效果图: 代码 import UIKit class ViewCo ...
- swift 学习之自动引用计数
swift 学习之自动引用计数 学习和研究的主要是"实例对象和实例对象直接的相会强引用所产生的内从泄漏"和"使用闭包产生的强引用造成的内存泄漏" 注意:只有以引 ...
- Swift学习目录
本学习基于苹果官方Swift学习材料,保留了原版90%左右的内容(一些项目开发中基本不用的知识点没有整理),并根据理解进行整理.如对原版感兴趣,可以直接单击链接阅读和学习. 第一部分 基础篇 1.基本 ...
- 【swift学习笔记】二.页面转跳数据回传
上一篇我们介绍了页面转跳:[swift学习笔记]一.页面转跳的条件判断和传值 这一篇说一下如何把数据回传回父页面,如下图所示,这个例子很简单,只是把传过去的数据加上了"回传"两个字 ...
随机推荐
- (9)EvenOddJump
一.问题描述 一只青蛙从数组(A)的每一个元素向数组尾部跳动.跳动规则如下: 当奇数跳的时候,就是第1.3.5.7....次进行移动时候,移动规则A[i] <= A[j], 并且A[j] = ...
- pyqt5-QWidget坐标系统和大小
获取坐标和尺寸: 坐标的获取视频教程:https://v.qq.com/x/page/t085892mzh9.html x() y() 返回控件的坐标 相对于父控件的坐标(窗口框架左上角) ...
- luogu P4899 [IOI2018] werewolf 狼火
传送门 首先很显然,从人形起点出发能到的点和狼形能到终点的点都是一个联通块,如果能从起点到终点则说明这两个联通块有交 这个时候可以请出我们的克鲁斯卡尔重构树,即对原图分别建两棵重构树,一棵边权为两端点 ...
- Ubuntu18.04安装搜狗拼音输入法皮肤透明解决方法
解决方法: 去搜狗输入法官网下载一个新的皮肤,然后右键用“搜狗输入法”打开,就解决了!!!
- 影子节点 shadowDOM
示例: <video controls autoplay name="media"> <source id="mp4" src="t ...
- org.springframework.beans.factory.CannotLoadBeanClassException-估计mapper出参 和 po字段不对应了
DEBUG [localhost-startStop-1] - Ignoring bean class loading failure for bean 'itemsService'org.sprin ...
- 超级简单的Android Studio jni 实现(无需命令行)【转载】
原文: http://www.jianshu.com/p/e689d0196a17 1.配置Anroid Studio(这步是关键) 使用[command+,] 打开Preferences,选择Ext ...
- C/C++ assert()函数用法总结
1. 简介 assert宏的原型定义在<assert.h>中,其作用是如果它的条件返回错误,则终止程序执行. 原型定义: #include <assert.h>void ass ...
- MySql联合查询
将多条查询语句的结果合并为一个结果 *多表查询是横向连接,联合查询是纵向连接. 语法: 查询语句1 union 查询语句2 union 查询语句3 *union关键字默认去重,union all包含重 ...
- 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 ...