Swift8-枚举Enumerations

枚举语法、使用Switch语句匹配枚举值、关联值、原始值、递归枚举。

 

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

C/C++中枚举为一组整型值分配相关联的名称。Swift中的枚举更加灵活,不必给每一个枚举成员提供一个值。如果给枚举成员提供一个值(称为“原始”值),则该值的类型可以是字符串、字符、或是一个整型值或浮点数。

枚举成员可以指定任何类型的关联值存储到枚举成员中,就像其它语言中的联合体(union)和变体(variants)。可以在一个枚举中定义一组相关的枚举成员,每一个枚举成员都可以有适当类型的关联值。

Swift中,枚举类型是一等类型。采用了很多在传统上只被类所支持的特性,例如计算属性(用于提供枚举值的附加信息)、实例方法(用于提供和枚举值相关联的功能)。枚举也可以定义构造函数来提供一个初始值;可以在原始实现的基础上扩展它们的功能;还可以遵循协议来提供标准的功能。

 

枚举语法:

使用enum关键词来创建枚举并且把它们的整个定义放在一对大括号内:

enum SomeEnumeration{

  //枚举定义放在这里

}

enum CompassPoint{

  case north

  case south

  case east

  case west

}

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

Swift枚举成员在被创建时不会被赋予一个默认的整型值。上面的north,south,east,west等不会被隐式赋值为0,1,2,3.相反,这些枚举成员本身就是完备的值,这些值的类型是已经明确定义好的CompassPoint类型。

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

enum Planet{

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

}

每个枚举定义了一个全新的类型。

var aa=CompassPoint.west

aa的类型可以在它被枚举CompassPoint的某个值初始化时推断出来。一旦aa被声明为CompassPoint类型,就可以使用更简洁的点语法将其设置为另一个CompassPoint的值:

aa=.east

当aa类型已知时,再次为其赋值可以省略枚举类型名。

 

使用switch语句匹配枚举值:

switch aa{

  case .west:...

  case .east:...

  ...

  default:break

}

switch语句必须穷举所有情况。如果忽略了枚举中某个取值,代码将在编译时期出错。

如果不需要匹配每个枚举成员,可用default分支来涵盖所有未明确处理的枚举成员。

 

关联值:

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

 

可以定义Swift枚举来存储任意类型的关联值,每个枚举成员的关联值类型可以各不相同。

enum Barcode{

  case upc(Int,Int,Int,Int)

  case qrCode(String)

}

上述定义了一个名为Barcode的枚举类型,它的一个成员值是具有(Int,Int,Int,Int)类型关联值的upc,另一个成员值是具有String类型关联值的qrCode。

var bb=Barcode.upc(1,2,3,4)

枚举成员可有多个,赋予一个变量/常量上的只有其中某一个。

case .upc(let a,let b,let c,let d)

case let .upc(a,b,c,d)

 

原始值:

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

enum Sheep:String{

  case xyy="xyy"

  case lyy="lyy"

}

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

 

原始值的隐式赋值:

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

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

 

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

没有原始值的枚举赋值的常量/变量,访问rawValue会编译出错。

 

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

enum point:String{

  case north,south,east,west

}

north的隐式原始值是"north",后面以此类推。

 

 

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

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

let possiblePlanet=Planet(rawValue:7)

这个方法获得的是一个可选值。Optional(xxx)。上例中是Planet?类型。无传入原始值对应的枚举成员是返回nil。

 

递归枚举:

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

也可以在枚举类型开头加上indirect关键字来表明它的所有成员都是可递归的。

enum aa{

  case a(Int)

  indirect case b(aa)

  indirect case c(aa,aa)

}

 

indirect enum bb{

  case a(Int)

  case b(bb)

}

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

func evaluate(_ expression: aa)->Int{

  switch expression{

  case let .a(value):

    return value

  case let .b(value):

    return evaluate(value)+evaluate(value)

  case let .c(vvv,mmm):

    return evaluate(vvv)*evaluate(mmm)

  }

}

 

let four=aa.a(4)  //声明两个a枚举类型的aa成员常量

let db=aa.b(four)  //

let prod=aa.c(db,four)

 

evaluate(four)  //返回结果4 直接返回值

evaluate(db)  //返回结果8 evaluate-> evaluate+evaluate

evaluate(prod)  //返回结果48 evaluate-> evaluate*evaluate-> (evaluate+evaluate)*evaluate

 

posted @ 2020-05-06 23:02  吉吉boy  阅读(147)  评论(0编辑  收藏  举报