Swift学习笔记8——枚举类(Enumerations)
2015-10-03 11:43
399 查看
这里为啥要叫枚举类而不是枚举类型呢?因为Swift中的枚举和C中的枚举很不一样。它已经可以看成一个类,可以看成一个类,可以看成一个类。重要的事情说三遍。此外,它是值传递!
在C中,枚举类型中的每一项都整形,然而在Swift中,你不必为每一项赋值。定义的时候所用的名字就是用来枚举的。当然你也可以为枚举成员赋值,这个赋值不单单是整形,可以是Charater,String,浮点数。
下面定义一个枚举类型。
定义一个枚举变量
Associated Value
用来给每一个枚举成员再定义一个补充值。下面是官方的例子。
我们知道商品的条形码和二维码。条形码是由一串数字组成的,这个数字分为了4个部分。而二维码其实是用一串很长的字符来编码的。如果要把二位码和条形码封装成为一个枚举类型,为了更好地区别二者,我们可以加上associated value,定义如下
定义Barcode变量,同是添加上associated value
答案是b1是Barcode类型,b2是(String) -> Barcode类型,一个函数类型。
所以当你想用
这里就可以看出了,其实Barcode.QRCode(String:)是一个构造函数,这里再次验证了swift中的枚举是一个类。
那为啥NameSet里面可以直接用.Tom之类来赋值呢?我的猜测是当你定义了associated value的时候,相当于把该枚举成员从一个值变为了构造方法。
switch语句来处理枚举类
接下来看看使用swift强大的switch语句来处理枚举类,除了一般的枚举成员之外,对于带associated value 的成员,我们还可以得到associated value。
我们修改一下上面的switch如下,你觉得那句会打印呢?
这里再回顾一下switch语句,之前说过只有穷尽枚举的时候才不需要default选项。上面的例子中因为把NameSet里面所有可能都枚举了,所以不需要default选项。
Raw Value
这个就是对每一项枚举成员绑定一个值,好比是C里面的枚举成员都是一个整形。
如果需要Raw Value,必须在声明枚举类的时候加上raw value 的类型。
比如官网例子
和C有默认的raw value一样,swift的枚举类也有默认的raw value。但是不是任何类型的raw value 都有默认值。假如你raw value的类型是Character,那么就不存在默认raw value,每个枚举成员的默认值都必须由你自己定义。
如果类型是Int,那么默认值第一个是0,后面的一项都前一项加1.看下面例子就明白了
如果类型是String,那么默认值就是你的枚举成员的名字。
如果有raw value,就可以用raw value来定义枚举变量
递归enum
就是在enum的枚举成员的associated value声明为本枚举类。然后使用递归函数。这里附上官方例子。实际的应用有待研究。
在声明associated value为自己枚举类的时候,需要加上indirect关键字。这个关键字可以加在每个case的前面,也可以加在enum的前面。后一种方法对里面所有的case都起效。但是并不要求所有case都有本枚举类作为associated value。
在C中,枚举类型中的每一项都整形,然而在Swift中,你不必为每一项赋值。定义的时候所用的名字就是用来枚举的。当然你也可以为枚举成员赋值,这个赋值不单单是整形,可以是Charater,String,浮点数。
下面定义一个枚举类型。
enum NameSet { //注意首字母已经大写 case Lucy case Tom case Kate case Aaron } enum NameSet2{ //可以将枚举成员都写在一行,用逗号分隔 case Lucy, Tom, Kate, Aaron }
定义一个枚举变量
var myName = NameSet.Aaron myName = .Kate //因为已经声明了myName是NameSet类型,所以改变值的时候可以直接用 .Kate
Associated Value
用来给每一个枚举成员再定义一个补充值。下面是官方的例子。
我们知道商品的条形码和二维码。条形码是由一串数字组成的,这个数字分为了4个部分。而二维码其实是用一串很长的字符来编码的。如果要把二位码和条形码封装成为一个枚举类型,为了更好地区别二者,我们可以加上associated value,定义如下
enum Barcode { case UPCA(Int, Int, Int, Int) //条形码 case QRCode(String) //二维码 }
定义Barcode变量,同是添加上associated value
var productBarcode = Barcode.UPCA(8, 85909, 51226, 3) productBarcode = .QRCode("ABCDEFGHIJKLMNOP")这里要注意的一点是,如果你定义了associated value,那么在定义变量的时候就和前面的NameSet不太一样了。看下面的两句代码
var b1 = Barcode.UPCA(8, 85909, 51226, 3) var b2 = Barcode.QRCodeb1和b2究竟是什么类型呢?
答案是b1是Barcode类型,b2是(String) -> Barcode类型,一个函数类型。
所以当你想用
b2 = Barcode.QRCode("fef") //error报错 不能将 Barcode类型是值赋给 (String)->Barcode.
这里就可以看出了,其实Barcode.QRCode(String:)是一个构造函数,这里再次验证了swift中的枚举是一个类。
那为啥NameSet里面可以直接用.Tom之类来赋值呢?我的猜测是当你定义了associated value的时候,相当于把该枚举成员从一个值变为了构造方法。
switch语句来处理枚举类
接下来看看使用swift强大的switch语句来处理枚举类,除了一般的枚举成员之外,对于带associated value 的成员,我们还可以得到associated value。
enum NameSet { //重新定义一个简单的枚举类 case Lucy case otherName(String) } var myName = NameSet.Lucy myName = .otherName("Alexs") switch myName { case .Lucy: print(myName) case .otherName(var inputName): //使用括号解包出associated value print(inputName) //只有这句会打印出 Alexs }
我们修改一下上面的switch如下,你觉得那句会打印呢?
switch myName { case .Lucy: print(myName) case .otherName: print("otherName") case .otherName(var inputName): print(inputName) }这里打印的是otherName,这里可以看出,switch里面的.otherName和声明枚举变量时候的不同,这里已经是值NameSet的值了。而且上面的Switch也会有警告说最后一个case永远不能执行。括号只是用来解包出associated value,而不是构造方法。为了验证这一点,再改改上面代码
var myName = NameSet.Lucy switch myName { case .Lucy(let name): print(name) case .otherName: print("otherName") case .otherName(var inputName): print(inputName) }你会发现这里打印了 (),因为解包Lucy没有得到值。
这里再回顾一下switch语句,之前说过只有穷尽枚举的时候才不需要default选项。上面的例子中因为把NameSet里面所有可能都枚举了,所以不需要default选项。
Raw Value
这个就是对每一项枚举成员绑定一个值,好比是C里面的枚举成员都是一个整形。
如果需要Raw Value,必须在声明枚举类的时候加上raw value 的类型。
比如官网例子
enum ASCIIControlCharacter: Character { case Tab = "\t" case LineFeed = "\n" case CarriageReturn = "\r" }
和C有默认的raw value一样,swift的枚举类也有默认的raw value。但是不是任何类型的raw value 都有默认值。假如你raw value的类型是Character,那么就不存在默认raw value,每个枚举成员的默认值都必须由你自己定义。
如果类型是Int,那么默认值第一个是0,后面的一项都前一项加1.看下面例子就明白了
enum NameSet: Int{ case Lucy //0 case Tom = 3 //3 case Kate //4 case Angle = 66 //66 case Alex //67 }
如果类型是String,那么默认值就是你的枚举成员的名字。
enum NameSet: String{ case Lucy //Lucy case Tom = "T" //T case Kate //Kate }
如果有raw value,就可以用raw value来定义枚举变量
var myName = NameSet(rawValue: "Lucy") //注意这里返回的是一个可选类型,因为这个构造方法是一个可失败的构造方法。具体看后面的类构造的文章。 print(myName!.rawValue) //这里我就没用if做判断了,直接强制解包
递归enum
就是在enum的枚举成员的associated value声明为本枚举类。然后使用递归函数。这里附上官方例子。实际的应用有待研究。
在声明associated value为自己枚举类的时候,需要加上indirect关键字。这个关键字可以加在每个case的前面,也可以加在enum的前面。后一种方法对里面所有的case都起效。但是并不要求所有case都有本枚举类作为associated value。
indirect enum ArithmeticExpression { //使用第二种indirect。定义了一个数学表达式。 case Number(Int) case Addition(ArithmeticExpression, ArithmeticExpression) case Multiplication(ArithmeticExpression, ArithmeticExpression) }
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 (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)) print(evaluate(product)) // prints "18"
相关文章推荐
- swift map
- 【面试必备】Swift 面试题及其答案
- 寒哥带你深入了解下Swift中的Value Type
- Swift-循环控制新特性
- Swift - 元组的用法
- Swift 运算符
- Swift学习(二)
- Swift学习(一)
- Swift中的数据类型
- 7.Swift翻译教程系列——控制循环的流程
- swift基础学习篇发布时间调整
- swift 中switch 的新用法
- swift实现ios类似微信输入框跟随键盘弹出的效果
- swift的类和对象
- swift的类与对象讲解
- swift的函数与闭包
- swift语法讲解及简单入门教程
- swift闭包
- swift函数
- Swift学习笔记7——闭包(Closures)