swift开发之optional类型(MD)

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

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

optional类型的数据结构
public enum Optional : 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))