首页 >Swift

对于Swift中Optional的新理解

2017-08-10 14:20 编辑: 四门三连 分类:Swift 来源:
  • 本文为CocoaChina网友fanf1025投稿

Normal Type 和 Optional Type(可选类型)

Optional是swift不同于C以及Objective-c的一种新概念。引进了这个概念之后,我们可以把类型分为普通类型(例如, String, Array ...)和可选类型(Optional Type)。

swift中使用普通类型表示值一定存在,用可选类型(Optional Type)来表示其所对应的值可能存在可能为nil。

Optional Type 的本质是一个枚举类型,它枚举的是None(nil)和NormalType,如下所示:

enum Optional {
    case None
    case Normal(T)
}

所以其实OptionalType和NormalType是一个包含关系。

我们在写代码的时候也会发现,对于一个要传入NormalType的函数,如果传入一个有枚举情况的Optional的值是会报错的:

open func appending(_aString:String) ->String

 var stringA : String = "a"
 let stringB : String? = "b"
 stringA.appending(stringB)    // 编译错啦

Optional Type的分类

Optional Type又分为Normal Optional(普通)和Implicitly Unwrapped Optional(隐式拆包)。

普通的可选类型用 '?' 来声明,表示该值可能存在可能为nil。相当于声明了一个包含 Optional.None和Optional.Some(T)的枚举类型。

隐式拆包用 '!' 来声明,表示确认该值不为nil,一定存在。相当于声明了Optional.Some(T)。

需要注意的是,声明为隐式拆包Optional的对象值可以为nil,也就是说 'let string : String! = nil' 编译器完全是可以通过的。但是在之后访问该对象值时,会抛出异常。这和Optional Type的拆包有关。

做了个实验:

var stringa : String! = nil
let stringb :Character? ="a"
stringa?.append(stringb!)     // 结果为 nil
stringa.append(stringb!)     // 崩溃啦

我们发现尽管stringa是隐式拆包的Optional类型,但是通过 '?' 来访问stringa 也是可以成功操作的,不会引发崩溃。由此猜想,

stringa?.append(stringb!)

其实干了这些事:

if stringa != nil {
   stringa!.append(stringb!)
} else {
   return
}

由此可以得出结论,隐式拆包的Optional只是给了Optional自动拆包的权限,并不代表这个值不能够为nil。o((⊙﹏⊙))o.

Optional Type的拆包

拆包其实相当于switch & case,如下所示:

var y = x!
switch x {
    case Some(value) : y = value
    case None: // raise an exception
}

所以要确保x确实有值的情况下再进行拆包。

拆包的几种比较安全的办法:1)if 语句 + 强制拆包(!);2)Optional Binding (if let);

结论

1. 无论声明的String?还是String!其实都是一个Optional,所以值都可能为nil;

2. 声明为隐式拆包的Optional(例如,String!),在取值时只是省略了判断其值是否为nil的过程。所以一定要在确认值不可能为nil的情况下再使用为隐式拆包;

3. 最安全的确保一个值不为nil的情况是声明为NormalType;

搜索CocoaChina微信公众号:CocoaChina
微信扫一扫
订阅每日移动开发及APP推广热点资讯
公众号:
CocoaChina
我要投稿   收藏文章
上一篇:【硅谷问道】Chris Lattner 访谈录
我来说两句
发表评论
您还没有登录!请登录注册
所有评论(0

综合评论

相关帖子

sina weixin mail 回到顶部