技术头条 - 一个快速在微博传播文章的方式     搜索本站
您现在的位置首页 --> iOS开发 --> Swift的多重 Optional

Swift的多重 Optional

浏览:862次  出处信息

   Optional 可以说是 Swift 的一大特色,它完全解决了 “有” 和 “无” 这两个困扰了 Objective-C 许久的哲学概念,也使得代码安全性得到了很大的增加。但是一个陷阱 -- 或者说一个很容易让人迷惑的概念 -- 也随之而来,那就是多重的 Optional。

   在深入讨论之前,可以让我们先看看 Optional 是什么。很多读者应该已经知道,我们使用的类型后加上 ? 的语法只不过是 Optional 类型的语法糖,而实际上这个类型是一个 enum:

enum Optional<T> : _Reflectable, NilLiteralConvertible {  
    case None
    case Some(T)

    //...
}

   在这个定义中,对 T 没有任何限制,也就是说,我们是可以在 Optional 中装入任意东西的,甚至也包括 Optional 对象自身。打个形象的比方,如果我们把 Optional 比作一个盒子,实际具体的 String 或者 Int 这样的值比作糖果的话,当我们打开一个盒子 (unwrap) 时,可能的结果会有三个 -- 空气,糖果,或者另一个盒子。

   空气和糖果都很好理解,也十分直接。但是对于盒子中的盒子,有时候使用时就相当容易出错。特别是在和各种字面量转换混用的时候需要特别注意。

   对于下面这种形式的写法:

var string: String? = "string"  
var anotherString: String?? = string  

   我们可以很明白地知道 anotherString 是 Optinal<Optional<String>>。但是除开将一个 Optional 值赋给多重 Optional 以外,我们也可以将直接的字面量值赋给它:

var literalOptional: String?? = "string"  

   这种情况还好,根据类型推断我们只能将 Optional<String> 放入到 literalOptional 中,所以可以猜测它与上面提到的 anotherString 是等效的。但是如果我们是将 nil 赋值给它的话,情况就有所不同了。考虑下面的代码:

var aNil: String? = nil

var anotherNil: String?? = aNil  
var literalNil: String?? = nil  

   anotherNil 和 literalNil 是不是等效的呢?答案是否定的。anotherNil 是盒子中包了一个盒子,打开内层盒子的时候我们会发现空气;但是 literalNil 是盒子中直接是空气。使用中一个最显著的区别在于:

if let a = anotherNil {  
    print("anotherNil")
}

if let b = literalNil {  
    print("literalNil")
}

   这样的代码只能输出 anotherNil。

   另一个值得注意的地方时在Playground 中运行时,或者在用 lldb 进行调试时,直接使用 po 指令打印 Optional 值的话,为了看起来方便,lldb 会将要打印的 Optional 进行展开。如果我们直接打印上面的 anotherNil 和 literalNil,得到的结果都是 nil:

(lldb) po anotherNil
nil

(lldb) po literalNil
nil  

   如果我们遇到了多重 Optional 的麻烦的时候,这显然对我们是没有太大帮助的。我们可以使用 fr v -R 命令来打印出变量的未加工过时的信息,就像这样:

(lldb) fr v -R anotherNil
(Swift.Optional<Swift.Optional<Swift.String>>)
    anotherNil = Some {
    ... 中略
}
(lldb) fr v -R literalNil
(Swift.Optional<Swift.Optional<Swift.String>>)
    literalNil = None {
    ... 中略
}

   这样我们就能清晰地分辨出两者的区别了。

建议继续学习:

  1. OpenStack Swift源码导读之——业务整体架构和Proxy进程    (阅读:2767)
  2. 你应该更新的Java知识之Optional    (阅读:2156)
  3. Openstack Swift简介    (阅读:1713)
  4. Swift 性能探索和优化分析    (阅读:1851)
  5. 自己动手使用 Swift 打造全功能 JSON 解析、生成库    (阅读:1191)
  6. Swift错误和异常处理    (阅读:837)
  7. Swift ABI 稳定对我们到底意味着什么    (阅读:967)
  8. Swift隐式解包 Optional    (阅读:673)
QQ技术交流群:445447336,欢迎加入!
扫一扫订阅我的微信号:IT技术博客大学习
© 2009 - 2024 by blogread.cn 微博:@IT技术博客大学习

京ICP备15002552号-1