【Swift4.0】可选类型

翻译能力有限,如有不对的地方,还请见谅!希望对Swift的学习者有所帮助,使用的编写工具:JQNote    InNote(iPhone)

在一个值可能缺失的情况下,你可以使用可选类型。一个可选类型代表两种可能:要么有一个值,并且你可以展开获取该可选类型的值。要么根本没有值。

可选的概念在C和Objective-C语言中是不存在。在Objective-C中最类似可选类型的功能是一个方法将返回nil或者一个对象,返回nil意味着“缺失一个有效的对象”。然而,这只适合于对象,不适合结构体,基本的数据类型,或者枚举值。对于这些类型情况,Objective-C中的方法会返回一个特殊值(例如NSNotFound)来表示缺失一个值。这类似于假定方法调用者知道该方法返回值有一个特殊的值需要检测。Swift的可选类型允许你不需要指定常量,可以为所有任何类型表示一个缺失值。

下面一个例子,说明如何使用可选类型来解决值缺失的问题。Swift中的Int类型有一个初始化方法:转化一个字符串为整数。但是,不是每个字符串都可以被转化为整数,例如,字符串“123”可以被转化为整数123,但是“Hello,world”没有一个明显的数字可以被转化。

letpossibleNumber= "123"

letconvertedNumber=Int(possibleNumber)

因为初始化方法可能会转化失败,所以它会返回一个可选类型的Int,而不是Int,写作Int?。问号表示值是可选的,意味着它可能包含了一些整数值,或者它可能根本没有值。

nil

如果你想设置一个可选类型的变量为没有值状态,那么可以通过赋给它一个特殊的值nil:

varserverResponseCode:Int?=404

serverResponseCode= nil

nil不能被用作非可选类型的常量或者变量。如果代码中需要一个常量或者变量在特定条件下有缺失值的情况,那么就要总是声明该变量或者常量为可选类型。如果你定义了一个可选的变量,并且没有设置缺省值,该变量会自动被设置为默认值nil:

varsurveyAnswer:String?  // surveyAnswer is automatically set to nil

Swift中的nil与Objective-C中的ni不同,在Objective-C中,nil是指向一个不存在的对象的指针,而在Swift中,nil不是一个指针—它是代表一个确定类型的值的缺失。任何可选类型 都可以被设置为nil,不仅仅是对象类型。

If 条件语句 和 强制展开

你可以使用If语句通过与nil的比较来判断是否一个可选类型包含一个值。使用“==”或者“!=”操作符来实现。

如果一个可选类型有一个值,那么它被认为是“不等于”nil:

ifconvertedNumber!=nil{

print(“convertedNumber contains some integer value.”)

}

一旦你能够确定某个可选 是包含一个值,那么你可以通过在可选类型的名字后面添加一个叹号(!)来获取它里面的值。这个叹号有效的说明:“我确切的知道这个可选已经有一个值;请使用该值。”这种方式被看作是 可选类型值的强制展开:

ifconvertedNumber!=nil{

print(“convertedNumber has an integer value of\(convertedNumber!).”)

}

如果使用!来获取一个不存在值的可选类型,那么会导致运行时错误发生。在使用叹号来强制展开可选值之前,总是要确定该可选是包含一个非空的值。

可选绑定

使用可选绑定来确定一个可选是否包含一个值,如果包含,使该值作为一个临时常量或者变量。可选绑定可以使用if和while语句来检查一个可选类型的值,并且取出这个值作为一个常量或者变量,如下所示,为一个if语句编写一个可选绑定:

if letconstantName = someOptional {

statements

}

下面我们可以重写下 possibleNumber 的例子,使用可选绑定,而不是强制展开:

if letactualNumber=Int(possibleNumber) {

print("\"\(possibleNumber)\" has an integer value of\(actualNumber)")

}else{

print("\"\(possibleNumber)\" could not be converted to an integer")

}

// Prints ""123" has an integer value of 123”

这段代码可以被解释为:“如果Int(possibleNumber)返回的可选Int包含一个值,那么把这个值设置给一个新的常量actualNumber”

如果转化成功,那么在第一个if条件语句中actualNumber常量变为可用,它已经被可选类型中所包含的值初始化了,因此这里就不再需要添加后缀!来获取它的值。常量和变量都可以用在可选绑定。如果你想要在if语句的第一个分支条件中操作actualNumber的值,那么你可以用if var actualNumber来替换,该可选所包含的值将作为一个变量而不是一个常量使用。

如果需要,一个if语句中可以包含多个可选绑定和布尔条件,使用逗号隔开。如果其中任何一个可选绑定的值为nil或者任何一个布尔值等于false,那么整个if条件语句被认为是false。如下:

if letfirstNumber=Int("4"),letsecondNumber=Int("42"),firstNumber

print("\(firstNumber) < \(secondNumber) < 100")

}

//Prints"4 < 42 < 100"

等同于

if letfirstNumber=Int("4") {

if letsecondNumber=Int("42") {

iffirstNumber

print("\(firstNumber) < \(secondNumber) < 100")

}

}

}

// Prints "4 < 42 < 100”

在if语句中用可选绑定创建的常量或者变量只在该if语句中可用,与之不同,在guard语句中创建的常量或者变量在guard下面的代码中都是可用的。

隐式展开的可选类型

如上面所说,可选表示了一个常量或者变量是允许存在“没有值”。可选的类型 可以用一个if语句来检查是否存在一个值,并且可以使用可选绑定来获取它的值,如果可选包含一个值的话。有时候,一个可选类型在第一次被设置了初始化值之后,在整个程序结构中,该可选总是清晰明确的有一个值。在这种情况下,就不需要每次都检查和展开该可选的值。它可以被直接获取,因为它一直都有值,是安全的。这类可选类型被称为隐式展开的可选类型。编写一个隐式展开的可选类型是通过在可选类型后面添加一个叹号(String!)而不是一个问号(String?)。隐式展开的可选类型也是一种普通的可选类型,但是,它可以像一个非可选类型值被使用,不需要每次都展开它的可选值。下面的例子展示了一个可选字符串与隐式展开的可选字符串之间在获取值上的不同:

letpossibleString:String? = "An optional string."

letforcedString:String=possibleString!// requires an exclamation mark

letassumedString:String! = "An implicitly unwrapped optional string."

letimplicitString:String=assumedString// no need for an exclamation mark”

你可以把一个隐式展开的可选类型看作为在使用时有权限自动展开它的值,而不需要每次使用时在可选后面再添加一个叹号。声明的时候在可选类型名称后面直接添加一个叹号。你也可以把一个隐式展开的可选看作为一个普通的可选,可以检查是否它包含一个值:

ifassumedString!=nil{

print(assumedString)

}

// Prints "An implicitly unwrapped optional string.”

你还可以对一个一个隐式展开的可选使用可选绑定,检查和展开它的值:

ifletdefiniteString=assumedString{

print(definiteString)

}

// Prints "An implicitly unwrapped optional string.”

不要对一个后续可能变为nil的变量使用隐式展开的可选类型,当后续需要检查一个变量是否为nil的时候,总是声明该变量为可选类型。

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

推荐阅读更多精彩内容