美文网首页
swift开发之optional类型(MD)

swift开发之optional类型(MD)

作者: littlewish | 来源:发表于2017-03-04 17:08 被阅读15次
    摘要: 针对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的诞生。

    老文地址

    相关文章

      网友评论

          本文标题:swift开发之optional类型(MD)

          本文链接:https://www.haomeiwen.com/subject/dydjgttx.html