★ iOS高级:Swift入门精讲③ 01 swift编程-02-枚举-01关联值

前言:

本篇仅为视频学习笔记

枚举的基本用法

我们开看一下,Swift中的枚举,一说到枚举,在以前学习C语言当中也知道,但是Swift的枚举对比C语言中的枚举,肯定是强大许多的。

回顾一下之前我们C语言的枚举,其实本质就是什么,本质就是整型。以前枚举,就是0、1、2、3、4这些整型,但是swift中的枚举就不一样了。

 enum Direction {
     case north
     case south
     case east
     case west
 }

根据上面代码,我们来看一下,枚举是怎么定义的?定义非常简单。直接enum,然后Direction是枚举的名称,内部那么多case就代表,枚举有多少个成员。那很明显Direction这个枚举类型,它有4个成员。Direction是方向的意思,它4个成员是东、南、西、北。

上面代码还可以这样写,它们完全是等价的如下:

 enum Direction {
     case north, south, east, west
 }

那么怎么用呢?很简单,如下:

  var dir = Direction.west
  dir = Direction.east
  dir = .north
  print(dir) // north

如果我们要定义一个枚举变量,我们定义一个dir枚举变量,再把Direction.west赋值给它。由于我们Swift编译器会自动推断dir这个类型,所以var dir = 不用声明类型。很明显它就是Direction类型的。

然后,一旦赋值完成之后呢,dir就是Direction这种类型。以后我们可以修改它的值,修改它的值,也只能给它赋值Direction中四个成员中的一个。因为这个类型,已经固定死了,就是Direction。

那么赋值的话,我们可以第一种Direction.east,赋值另外一个值。那么,一当你确定了这个dir是Direction类型,那你可以在赋值过程中可以省略前面的Direction,直接 .north。其实就是case north这个家伙赋值给了dir。

那么到时候,我们直接打印枚举的话,它会将dir成员的名字打印出来。可以自己去尝试一下。


 switch dir {
 case .north:
     print("north")
 case .south:
     print("south")
 case .east:
     print("east")
 case .west:
     print("west")
 }

然后,他也可以用在switch语句中,如上。switch这个dir。我们知道swift语句要保证处理所有情况,很明显dir是Direction类型的。Direction类型一共有4个值(成员),我们case 4个,其实就可以了。

关联值 (Associaated Values)

那么,我么再来看一下关联值,我们swift枚举中是可以设置一个关联值的。那是什么意思呢?

★ 有时会将枚举的成员值跟其他类型的关联存储在一起,会非常有用

例子 - 1

相当于就是这样子,如下:

 enum Score {
     case point(Int)
     case grade(Character)
 }

比如说,分数Score这个枚举,我们知道分数的话,很多时候分数可能分两种,一种是有具体的值的 case point(Int),比如说你考了96分,98分,100分,那这种分数是有具体值的。但有时候,地方的考试成绩给你的分数,case grade(Character)可能给你拿A,还是拿B,还是拿A+,A、B、C、D 四个等级。

所以说分数可能是有数值的,或者是用A、B、C、D四个字符来表达。所以说,分数有两种情况。所以呢,可以如下面那样定义:

case point(Int)
case grade(Character)

也就是说,如果我们要定义一个分数变量的话,如下:

 var score = Score.point(96)
 score = .grade("A")

那么,第一种情况,我们可以Score.point(96),point就是具体的分数,我可以传一个96进去,那么这个96其实就相当于 point(Int)中的Int。那么就这样的话,就将这个96跟我们的score这个枚举变量关联起来了。然后呢,

然后呢,由于我们这个分数呢,也可以是case grade(Character)这种类型,所以呢,我可以给它赋值另外一个** .grade("A")**,但是它接收的是一个字符(Character),比如说,比考的这个分数的等级,你这个成绩是A,那么我们可以传进去一个A给你。

你看,这就很好表达了,成绩有两种,一种是用数值来表达,一种是用字符来表达。

而且,再思考一个问题,枚举一般用在什么地方。是不是你这个变量的取值,就那固定的几种,就应该用枚举。

比如说,一年有多少个季节,这个季节season,这种东西肯定用枚举比较好,因为只有春夏秋冬,这4个季节。所以,季节一般我们用枚举,是最好的。那分数也不是一样吗?我们现在分数就两种,要么就是有数值的,要么是有字符的,说一分数就两种选择,所以把它定义为枚举,还是比较合适的。


    switch score {
    case let .point(i):
        print(i,"point")
    case let .grade(i):
        print("grade",i)
    } // grade A

那么再来举一个例子,我们先看一下这个switch用在score上面是怎么用的,很简单。一共有两种情况,要么是.point,要么是.grade。这两种嘛,而且呢,由于Int和Character,是到时候可以关联一个值,接收一个值的。

所以呢,建议大家再做case的时候 case let .point(i): ,point里面是要写一个值的,比如说这个i

那么这个i你要它变成常量呢?还是变量呢?你就可以再左边写一个let或者var,这个取决于你自己。

那我们这个score最后,给它赋值的是score = .grade("A"),很明显这个score是符合这个 case let .grade(i): 的。到时候这个A会赋值给这个 i,所以,最后这个print(i,"grade")打印出来,肯定是grade和这个A。合起来就是 // grade A

整体代码

例子 - 2

 enum Date {
     case digit(year: Int, month: Int, day: Int)
     case string(String)
 }
 
 var date = Date.digit(year: 2011, month: 9, day: 10)
 date = .string("2011-09-10")
 
 switch date {
 case .digit(let year,let month,let day):
     print(year, month, day)
 case let .string(value):
     print(value)
 }

这是一个日期Date,日期也是一样的,我们可以有两种表达形式,第一种表达形式case digit(year: Int, month: Int, day: Int)是用数字的形式,比如所你传年、月、日,代表日期。第二种表达形式case string(String),你可以直接传一个字符串给我。


我们再来看一下,现在的这个日期Date枚举?日期Date的第一个枚举成员,注意看,跟例1中的Score枚举中的第一个枚举成员,有什么区别。之前Score,它的第一个枚举成员关联的类型,是没有写名称的,但是在Date第一个枚举成员中,我们关联的类型是写名称的,其实,如果你乐意的话,完全可以写几个名称,来表达一下,这三个值代表什么。所以,你看我写了一个year、 month、day。其实这三个名称,这三个标签,你是可以省略的,但有时候,你想让别人明确的知道你想要什么,所以可以写一个标签名。

那么,我们来看一下,那么怎么定义一个这样的变量?其实,很简单,如下:

var date = Date.digit(year: 2011, month: 9, day: 10)
date = .string("2011-09-10")

日期有两种表达形式,所以什么情况下用枚举呢?如果你这个类型,只有几个固定的取值的,那么就可以用枚举

那么,这个switch date 也是一样的,那么这个switch再扩展一个,由于digit,它接收了三个家伙,所以肯定有year、month、day的,跟前面讲的那个有什么不一样。

前边讲的这个let修饰词,就是常量修饰词,我是写在这个整体的前面。那么,digit你会发现三个year、month、day是单独写的。

那是,什么意思呢?也就是.digit(let year,var month,let day)中year、month、day哪个是常量,哪个是变量,都收完全可以自己定的。


但是如果你这三个家伙,什么都不写,统一把这个let写到了整体的前面,代表year、month、day都是let 。如果你在前面统一写了一个var,那么year、month、day代表的就是变量,那么我们case一下,就可以把它们当作变量来使用。

 case let .string(value):

这个let写在前面,就代表value它是常量,当然这个let 你可以放到value 前面,也是可以的。


 var score = Score.point(96)
 score = .grade("A")

这就是关联值,但时候我这个枚举变量,可以把其它类型的值,关联存储在一起,也就是说这个score变量它的内存中其实是有96这个值的,那么第二个score如果存储这个A的话,也就意味这这个score它内存中是有这个A字符的内容的。

 var date = Date.digit(year: 2011, month: 9, day: 10)
 date = .string("2011-09-10")

还有这个date变量,到时候它的内存中是有2011、9、10这三个整型值,也就是说这三个整型值,其实是存储在date这个枚举变量的内存里面。那么下面这个字符串也是一样的。


关联值,你可以认为将各种类型的数据直接存储在枚举变量里面,这个呢,我们称之为关联值。

★ 必要时,let也可以改成var

关联值举例

比如说,我们讲的密码,我们手机的密码一般有两种,一种是输入密码,一种是输入数字。

数字这个举例是4个,输入4个数字作为你手机的解锁密码,当然你也可以用手势密码。那么,密码输入,既然就两种,我们是完全可以想象成枚举的,因为你就两种取值。

 enum Password {
     case number(Int,Int,Int)
     case gesture(String)
 }

所以,我们注意看,你这密码有两种,第一种是数字密码,数字密码我只要求你输入4个,所以是不是,我们就关联4个整型数据。还有一种是手势密码,所以叫gesture。那么手势密码我们就用字符串来表达。

那么怎么用字符串来表达呢?比如说,像这个密码盘我们就可以怎么做呢,我们就可以从左到右,从上到下,给它们编一个序号,比如说:1、2、3、4、5、6、7、8、9。其实如图所示,这个手势密码呢就是12369。那么为什么用字符串呢?我们思考一下,这个手势密码是不是可能很复杂。经过的路径比较多。如果你用整型表达,可能很不完整。那么,我们干脆,用字符串,这样更好。

var pwd = Password.number(3, 5, 7,8)
pwd = .gesture("12369")

假如我们的密码是3,5,7,8,手势密码按照刚才的12369,我们就可以这样表达。

 enum Password {
     case number(Int,Int,Int,Int)
     case gesture(String)
 }
 
 var pwd = Password.number(3, 5, 7,8)
 pwd = .gesture("12369")
 
 
 switch pwd {
     case let .number(n1, n2, n3, n4)
     print("number is",n1,n2,n3,n4)
     case let .gesture(str)
     print("gesture is",str)
 }
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,233评论 6 495
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,357评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,831评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,313评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,417评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,470评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,482评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,265评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,708评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,997评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,176评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,827评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,503评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,150评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,391评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,034评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,063评论 2 352

推荐阅读更多精彩内容