swift开发之optional类型(MD)

摘要: 针对swift新增的安全类型optional类型的概念理解,以及在开发过程中的一些使用和注意事项。新手开发,仅已此文备忘,如有错误,还请斧正。

tips:本人开发经验不多,如文章有概念错误,还请各位指正,原创文章,转载请注明出处。

optional类型的数据结构
public enum Optional<Wrapped> : ExpressibleByNilLiteral {

    /// The absence of a value.
    ///
    /// In code, the absence of a value is typically written using the `nil`
    /// literal rather than the explicit `.none` enumeration case.
    case none
    /// The presence of a value, stored as `Wrapped`.
    case some(Wrapped)
}

optional类型是一个枚举类型,有两个枚举值:

  • None类型

  • Some(Wrapped)

这两个类型决定了optional类型的概念和含义,有值或者没有值:

1 optional.None表示该类型没有值,也就是nil。(特别声明,swift中的nil不在有指针含义,而是表示且仅表示optional的.None)。

2 optional.Some(Wrapped)这是表示有值的情况,Some类似于java或者c++的泛类型的含义,Wrapped 类似是封装的值。

optional的wrap和unwrap

使用optional类型,该类型会对赋值过程和取值进行一些处理。

1 赋值也被称为装包的过程(wrap),optional类型会获取当前值的类型和具体值,如int类型的数字100.当一个optional类型被赋值为这个值时,其实optional记录了对应的类型(some)int,和值部分(wrapped)100.

2 取值也被称为解包的过程(unwrap),optional根据记录的类型(some)如上面说的int,和值部分(wrapped)100,新建一个some(wrapped)同int(100)返回给程序

如何声明一个optional类型

声明optional类型十分简单,我们平常声明一个字符类型是这样的

let str : string = "hello world"

如果想声明一个optional类型,只需要

let str : string?

或者

let str : string! = @"hello world"

在类型后面加一个?或者!,那么你现在持有的这个变量就是optional类型变量了。十分简单。

?和!声明的optional类型的区别

上面我们提到了optional的使用过程有装包和解包的过程,装包过程是不需要我们自己处理,但是解包的过程是需要开发者简单处理的。而声明时使用?和!的不同就表现在解包的过程。

optional类型的解包方法有下面这些
  • 直接在变量后面使用!进行解包

  • 使用if或者guard语句进行解包

  • 使用!声明的optional变量,使用时自动调用解包

第三点已经说出了使用!和?声明变量时的不同了,就是使用!声明的optional变量在后续的使用中,不需要再进行解包操作,当需要解包时,系统会对该变量自动解包处理。而使用?声明的optional变量则需要使用上面说明的1)或者2)其中一种方法解包,才能继续使用。

那么问题来了,既然能自动解包,那么都声明成!不就好了,还省事。optional是swift特别提出的安全类型,它的安全精髓就体现在解包这个步骤上。optional类型的解包是有崩溃的风险的。一个没有值也就是nil(optional.None)的optional变量,强行解包的话,程序是会直接crash。

var str : string!

print(str) //cash str is optional.none 

输出时,你会得到一个error,要是在项目中,不进行判断直接对没有值的optional变量强行解包的话,程序会crash。

所以总结来说,会crash或者得到一个error的原因就是optional类型变量在解包那一刻没有值。所以在开发过程中,如果你的optional是用!声明的,你就得确保在它的生命周期内,它不可能是nil,这是使用!声明的前提。而使用?声明虽然要在每次使用之前解包,但是我们可以在解包的过程进行一些判断操作,当变量是nil时做一些合适的处理。

如何才是安全正确的解包姿势呢

1 使用!直接解包是粗暴的,是不温柔的

2 swift针对optional安全类型,特别对if和guard语句做了处理,使用if和guard语句解包是安全的,温柔的

var firstName :String?

if let tempName =  firstName{

  print(tempName)

}else{

  print("firstName is nil")

}

if后面的的let语句就实现了安全解包的过程。如果firstName有值的话,tempName能获取到firstName的值。在if语句内,可以放心使用。

guard语句也有同样的效果

guard let tempName = firstName else{

  print("firstName is nil")//nil时做一些特殊处理

  return

}

print(tempName)

guard语句更加突出错误时的处理,还有一个优点就是,你let声明的tempName在guard语句外可以正常使用。

总结:optional是swift特别声明的安全类型,在使用过程中如果处理得当的话可以防止以前oc上很多因为数据没值导致的crash。个人还是比较推荐使用的,虽然有时候有些解包的过程感觉特别麻烦,但这都是一道道安全门,阻断了很多crash的诞生。

老文地址

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

推荐阅读更多精彩内容

  • Hello Word 在屏幕上打印“Hello, world”,可以用一行代码实现: 你不需要为了输入输出或者字符...
    restkuan阅读 3,144评论 0 5
  • 基础部分(The Basics) 当推断浮点数的类型时,Swift 总是会选择Double而不是Float。 结合...
    gamper阅读 1,255评论 0 7
  • 对各种值为"空"的情况处理不当,几乎是所有Bug的来源。 在我们的例子里,尽管tmp的值是nil,但调用tmp的r...
    AKyS佐毅阅读 10,492评论 1 13
  • 86.复合 Cases 共享相同代码块的多个switch 分支 分支可以合并, 写在分支后用逗号分开。如果任何模式...
    无沣阅读 1,336评论 1 5
  • 1. 用第一台mac申请调试证书 2.安装证书到keychain后,右击它生成p12 3.把p12证书和provi...
    Hollylord阅读 321评论 0 1