Swift学习:可选型的使用

本篇将详细总结介绍Swift可选型的用法;
顾名思义,可选类型表示一个变量可能有值,也可能没有值(nil),但是它的用法却与OC中的nil完全不同

主要内容:
1.可选型使用要点
2.可选型解包
3.可选链 Option chaining
4.空合并运算符nil coalesce
5.隐式可选型
6.可选型使用的其他示例
7.最后小结

一、可选型使用要点

  1. 可选类型类似于OC指针的nil值,但是OC中的nil只对类有用,而可选择型中nil对所有类型都可用,更安全
  2. 可选型的声明的方式是“数据类型+问号”。如:var errorCode :Int? = 404
  3. 当要使用一个可选类型的变量时,要在后面加感叹号“!”或者“?”。
  4. 不能把一个可选型便量赋值给非可选型的变量, 如:let tempValue = nil //报错
  5. 可选型数据一般都是可变的,所以一般情况下,可选型的数据也通常是变量
  6. 声明一个可选型的时候,必须是添加?,swift不能隐式的自动推断可选型
    swift不能用同类中的一个特殊值代表无或者没有,nil代表没有,但是却不能直接使用,如下:
var errorCode :Int = 404
errorCode = nil //报错

//改:使用Int?  声明一个整型可选型
var errorCode :Int? = 404
errorCode = nil //将其声明为为可选型变量才能赋值为nil

二、可选型解包

可选型数据,就意味着其值是可以为nil的,这样的数据不可以直接使用,所以将可选型解包后再使用是十分重要的操作。

//直接使用
var errorCode: String? = "404"
print(errorCode)
//"The errorCode is" +errorCode //直接使用显式可选型会编译不通过,报错

解包方法1:普通的if判断,不方便

if(errorCode != nil){
    "The errorCode is " + errorCode!
}else{
    "No error"
}

解包方法2:强制解包,使用感叹号“!”,存在错误风险。

//一般情况下,我们在确定使用的可选型变量不会是nil,才通过!强制解包并使用
var errorCode: String? = "404"
"The errorCode is " + errorCode!

解包方法3:尝试解包,使用问号“?”,较为安全

//当不确定使用的可选型变量是否是nil,通过?执行调用方法等操作,意味着不为nil时才可以执行成功
var errorCode: String? = "404"
"The errorCode is " + errorCode?

解包方法4:if-let解包, 当我们希望在可选型为nil时候执行别的代码,更适合使用使用if let方式解包

if let unwrappedErrorCode = errorCode{
    //unwrappedErrorCode 是经过解包的数据,得到非nil值
    "The errorCode is" + unwrappedErrorCode
}else{}

------------优美的分割线-----------------
 //if-let解包方法的改进:可以使用原来的变量名
if let errorCode = errorCode{
    //errorCode 是经过解包的数据,得到非nil值
    //括号内的errorCode 只在此括号内使用
    "The errorCode is" + errorCode
}else{
    //处理nil情况
}

解包时注意事项:

//1.隐式声明的可选型不需要解包,但是这样可能因为nil报错(详情请看第五部分)
var blog:String! = “helloWord"
//blog = nil 
"My blog is" + blog

//2.if-let可以同时解包多个变量,同时因为使用了if,也可以增加判断逻辑
if let errorCode = errorCode, errorMessage = 
                  errorMessage where errorCode == "404" {
    print("Page not found")
} else {
    print("No error")
}

三、可选链 Option chaining

可选链的使用简化了可选型的使用。在某些情况下可以避免if-let 解包的使用,而是通过尝试解包(使用问号?)或者强制解包(感叹号!)来使用操作对象
示例:

var errorCodeStr: String? = "Hello, playground"
//errorCodeStr.uppercaseString ; errorCodeStr是可选型不能直接使用,需要解包如下:
if let errorCodeStr = errorCodeStr{
    errorCodeStr.uppercaseString
}

上述代码使用可选链简化,如下:

//推荐写法:使用?尝试解包,如果成功就会将字符串大写
errorCodeStr?.uppercaseString
//不安全写法,当errorCode为nil时报错,除非我们确保errorCodeStr不为nil才能这样写
errorCodeStr!.uppercaseString

基于这样的使用,可能会出现类似 Person?.address?.addressName 的使用,这就构成了可选链,调用链中任何一个节点为nil,整个调用都会失败,返回nil,使用?是安全的。


四、空合并运算符nil coalesce

空合并运算符:解决解包之后的存值问题
示例1:

var uppperCaseErrorStr = errorCodeStr?.uppercaseString
//uppperCaseErrorStr此时是一个可选型变量,不需要显示声明,因为后面的表达式是可选型
//实现解包同时实现了大写
if let errorCodeStr  = errorCodeStr?.uppercaseString{
    errorCodeStr
}

示例2:

var errorMessage: String? = nil
let message: String
if let errorMessage = errorMessage{
    message = errorMessage
}else{
    message = "no error"
}

改进示例2:使用三目运算符

let message2 = errorMessage == nil ? "no errror" :errorMessage;

改进示例2:使用空合并运算符??,如果errorMessage有值,使用errorMessage!赋值

//??是空和并运算符
let message3 = errorMessage ?? "no error"

五、隐式可选型

  1. 区别于显式可选型的创建:类型+?,创建隐式可选型使用:类型+!
  2. 隐式可选型变量使用时,相当于其后面自带了一个感叹号,可以直接赋值给一个非可选型变量,但是隐式可选型依然保持可选型的特性,可以被赋值为nil,这就体现出来隐式可选类型的优点,即可用被赋值为nil,也可以不用每次显式的解包
  3. 隐式解析可选类型还可以在类中做属性,解决循环引用问题。
    示例:
var errorMessage: String! = nil
errorMessage = "not found"
//这里errorMessage是隐式可选型,使用时候不需要显式的解包,但是如果errorMessage为nil就会报错
"The error is " + errorMessage

六、可选型使用的其他示例

示例1.

var error1:(errorCode: Int, errorMessage: String?) = (404 , "page not found")
error1.errorMessage = nil
//error1 = nil 整个元组并非可选型,不能使用nil赋值

示例2.

var ageInt: String = "xyz"
//使用强制转换之后,age是可选型,需要按照可选型的规则去使用
var age = Int(ageInt)
if let age = age where age < 20{
    print("you are a tennager!")
}

示例3.

var greeting = "hello"
//rangeString 返回一个可选型,需要按照可选型的规则去使用
greeting.rangeOfString("ll") //2..<4
greeting.rangeOf3String("oo")//nil

七、最后小结

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

推荐阅读更多精彩内容